【问题标题】:How can I pass an absolute path via the command line to a parameter in XSLT 1.0 (using msxsl.exe)?如何通过命令行将绝对路径传递给 XSLT 1.0 中的参数(使用 msxsl.exe)?
【发布时间】:2016-04-26 22:01:46
【问题描述】:

我有一个由 WiX 的 heat 实用程序生成的 WXS 文件。我正在尝试使用(现有)exclusions.xslt 文件对其进行修改,以根据另一个 XML 文件的内容自动排除某些组件(我将其称为 parts.xml强>)。 xslt 文件目前用于从安装程序中删除一些组件/文件/目录,但用于相对静态的列表。

但是,就目前而言,我主要关心的是让它从参数加载和存储正确的路径并将其内容存储在变量中。

这是应用转换的方式(一旦 WiX 完成对文件“before.wxs”的加热采集):

msxsl.exe "before.wxs" "exclusions.xslt" -o "after.wxs" srcroot="$(SrcRoot)"

我传入 srcroot 作为 XSLT 文件中的一个参数,用于在用户机器上查找 parts.xml

从命令行获取参数并将所有反斜杠替换为正斜杠:

<!-- Adapted from http://stackoverflow.com/a/30153713/5605122 and http://geekswithblogs.net/Erik/archive/2008/04/01/120915.aspx-->
<xsl:param name="srcroot" />
<xsl:variable name="filename">
    <xsl:call-template name="string-replace-all">
        <xsl:with-param name="text" select="concat('file://', $srcroot, '/foo/parts.xml')" />
        <xsl:with-param name="replace" select='\\' />
        <xsl:with-param name="by" select='/' />
    </xsl:call-template>
</xsl:variable>
<xsl:variable name="myparts" select="document($filename)" />

我从here 得到的字符串替换全部是:

<!-- XSL 1.0 string-replace-all, taken from: http://geekswithblogs.net/Erik/archive/2008/04/01/120915.aspx -->
<xsl:template name="string-replace-all">
    <xsl:param name="text" />
    <xsl:param name="replace" />
    <xsl:param name="by" />
    <xsl:choose>
        <xsl:when test="contains($text, $replace)">
            <xsl:value-of select="substring-before($text,$replace)" />
            <xsl:value-of select="$by" />
            <xsl:call-template name="string-replace-all">
                <xsl:with-param name="text"
                select="substring-after($text,$replace)" />
                <xsl:with-param name="replace" select="$replace" />
                <xsl:with-param name="by" select="$by" />
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$text" />
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

我收到一个相当无用的错误:

代码:0x80004005 查询字符串中有意外字符。

但如果我只删除我发布的代码 sn-ps,错误就会消失。我不知道如何调试它并弄清楚发生了什么,但在仔细阅读之后,我相信我对我认为应该发生的事情有一个根本的误解,而不仅仅是一个拼写错误或语法错误。

最终,我希望将parts.xml 的内容存储在“myparts”中。我在这里错过了什么?

谢谢!

【问题讨论】:

  • 您有一个参数$src 和另一个$srcroot,如果sn-ps 完成,应该会报错。
  • 啊,哎呀,这实际上是一个错字,将其复制到此处(我将其重命名以更清楚地了解其用途)。我已经用修复编辑了这个问题。实际文件没有这个错字,但我在这里将它们全部更改为“srcroot”。谢谢。事实证明,我也错过了使用来自here 的代码,我必须将字符串用双引号和单引号括起来。如果可行,我将进行必要的更改和更新。

标签: xml xslt wix xslt-1.0 msxsl


【解决方案1】:

事实证明,我只需要将字符串文字设置在单引号中(反斜杠不需要转义)。我的 srcroot 也有一个尾随反斜杠,所以我从一开始就省略了它。这是更新的代码:

<!-- Adapted from http://stackoverflow.com/a/30153713/5605122 and http://geekswithblogs.net/Erik/archive/2008/04/01/120915.aspx-->
<xsl:param name="srcroot" />
<xsl:variable name="filename">
    <xsl:call-template name="string-replace-all">
        <xsl:with-param name="text" select="concat($srcroot, 'foo/parts.xml')" />
        <xsl:with-param name="replace" select="'\'" />
        <xsl:with-param name="by" select="'/'" />
    </xsl:call-template>
</xsl:variable>

至于如何测试的问题,我终于得到了它来检查文件是否存在,方法如下:

由于我使用的是 msxsl,因此我决定为 fileExists 函数使用扩展名:

<!-- Adapted from https://www.stylusstudio.com/SSDN/default.asp?action=9&read=2993&fid=48 -->
<msxsl:script language="JScript" implements-prefix="user">
<![CDATA[
fso = new ActiveXObject("Scripting.FileSystemObject");
function fileExists(filename){
return fso.FileExists(filename);
}

// With .NET XSLT processor we need to use the Framework API
//function fileExists(filename){
//return System.IO.File.Exists(filename); 
//} 

]]>
</msxsl:script>

在模板中,我做了以下检查:

<xsl:if test="not( function-available('user:fileExists') )">
        <xsl:message terminate="yes">
            <xsl:text>Required facilities are not available.</xsl:text>
        </xsl:message>
</xsl:if>

如果通过了,我做了以下事情:

<xsl:choose>
    <xsl:when test="user:fileExists(string($filename))">
        <xsl:message terminate="yes">
            <xsl:text>File found! Here:</xsl:text>
            <xsl:copy-of select="$filename"/>
        </xsl:message>
    </xsl:when>
    <xsl:otherwise>
        <xsl:message terminate="yes">
            <xsl:text>File cannot be found:</xsl:text>
            <xsl:copy-of select="$filename"/>
        </xsl:message>
    </xsl:otherwise>
</xsl:choose>

除非我出于某种原因设置了 terminate="yes",否则消息不会输出到控制台,因此这会暂停构建,我必须将其删除,但它帮助我调试并发现参数已被 XSLT 文件成功接收,并且我能够检查该路径中的文件是否存在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 2020-07-02
    • 1970-01-01
    • 1970-01-01
    • 2013-06-03
    • 1970-01-01
    相关资源
    最近更新 更多