我有一个WXS文件,它是由WiX的热效用产生的。我试图用一个(现有的) 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)" />从这里得到的字符串-替换-我得到的是:
<!-- 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查询字符串中的意外字符。
但是如果我只删除我发布的代码片段,错误就会消失。我不知道如何调试它并弄清楚到底发生了什么,但是在仔细研究之后,我相信我对我认为应该发生的事情有一个根本的误解,而不仅仅是一个错误或语法错误。
最终,我希望将parts.xml的内容存储在"myparts“中。我在这里错过了什么?
谢谢!
发布于 2016-01-21 19:49:03
结果,我只需要用单引号设置字符串文本(反斜杠不需要转义)。另外,我的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=设置为“是”,否则不会将消息输出到控制台,因此这将停止构建,我将不得不删除它,但它帮助我调试它,并发现该参数已被XSLT文件成功接收,并且我能够检查该路径上的文件是否存在。
https://stackoverflow.com/questions/34910529
复制相似问题