我正在尝试使用XSLT更新XML文件(由WiX生成)。我的工作几乎完美。但是,我找到了一个内部引用,我也需要替换它,它有点复杂。
简而言之,我在几个XML节点中将_32x附加到Id的值。但是,我在XML中找到了Id的引用,它也必须附加。
即原始XML文件(大大简化并删除了其他属性):
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="WEBINSTALLFOLDER">
<Directory Id="dir1DB31186637C634CBA8E0643DF80869C">
<Component Id="cmp65024F0DF585708F9ABEBE2F58FF64BA">
<File Id="fil8C400D2459FD744947D08FD584B820E4" />
<RegistryValue Value="ASP.dashboard_aspx" />
<RegistryValue Value="App_Web_10b5qifx" />
<RegistryValue Value="v4.0.30319" />
<RegistryValue Value="file:///[#fil8C400D2459FD744947D08FD584B820E4]" />
</Component>
</Directory>
</DirectoryRef>
</Fragment>
</Wix>
我的XSLT正确地将_32x附加到组件和文件中的Id值(并添加对Definitions.wxi的引用)。所有这一切都运行得很好,但我还必须更改任何具有值为'file:/// [#...'的RegistryValue节点,其中的新值将']'替换为'_32x]'。
也就是说,新标签应为:
<RegistryValue Value="file:///[#fil8C400D2459FD744947D08FD584B820E4_32x]" />
我目前的XSLT是:
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="wix:Wix">
<xsl:copy>
<xsl:processing-instruction name="include">..\Definitions.wxi</xsl:processing-instruction>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<!-- Identity transform. -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="@Id[parent::wix:Component]">
<xsl:attribute name="Id">
<xsl:value-of select="." />
<xsl:text>_32x</xsl:text>
</xsl:attribute>
</xsl:template>
<xsl:template match="@Id[parent::wix:File]">
<xsl:attribute name="Id">
<xsl:value-of select="." />
<xsl:text>_32x</xsl:text>
</xsl:attribute>
</xsl:template>
最终的XML RIGHT NOW,没有对RegistryValue进行更正:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include ..\Definitions.wxi?>
<Fragment>
<DirectoryRef Id="WEBINSTALLFOLDER">
<Directory Id="dir1DB31186637C634CBA8E0643DF80869C">
<Component Id="cmp65024F0DF585708F9ABEBE2F58FF64BA_32x">
<File Id="fil8C400D2459FD744947D08FD584B820E4_32x" />
<RegistryValue Value="ASP.dashboard_aspx" />
<RegistryValue Value="App_Web_10b5qifx" />
<RegistryValue Value="v4.0.30319" />
<RegistryValue Value="file:///[#fil8C400D2459FD744947D08FD584B820E4]" />
</Component>
</Directory>
</DirectoryRef>
</Fragment>
</Wix>
我是XSLT的新手,因此,不确定如何在RegistryValue节点的Value上进行替换,特别是在该文件:/// [#..并进行替换。
这在我的XML文件中反复出现,具有不同的实际文件ID,因此无法进行简单的硬编码常量替换。
谢谢
答案 0 :(得分:1)
添加此模板会有所帮助:
<xsl:template match="@Value[parent::wix:RegistryValue and matches(.,'^file:///\[#.*\]$')]">
<xsl:attribute name="Value">
<xsl:value-of select="concat(substring-before(.,']'), '_32x', ']')"/>
</xsl:attribute>
</xsl:template>
答案 1 :(得分:1)
我还必须使用Value更改任何RegistryValue节点 'file:/// [#...'使用新值替换']'和'_32x''。
即使没有正则表达式,你也可以这样做:
<xsl:template match="wix:RegistryValue/@Value[starts-with(., 'file:///[#')]">
<xsl:attribute name="Value">
<xsl:value-of select="substring-before(., ']')" />
<xsl:text>_32x]</xsl:text>
</xsl:attribute>
</xsl:template>