2015-04-12 128 views
0

我想用XSLT更新XML文件(由WiX生成)。我的工作幾乎完美。但是,我發現了一個內部參考,我也需要更換,而且這個參考有點複雜。XSLT - 屬性更改(正則表達式?)

簡而言之,我將_32x附加到多個XML節點中的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值在組件和文件正確(並增加了定義的參考。 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眼下,沒有對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節點的值上進行替換,何時特別是那個file:/// [#..並且做替換。

這個反覆發生在我的XML文件中,具有不同的實際文件ID,因此不可能使用簡單的硬編碼常量替換。

謝謝

+0

你沒有提到你是否能夠使用XSLT 2.0,這使得這種事情很簡單。 –

回答

0

我也必須更改任何RegistryValue節點與 值 '文件:/// [#...' 與用'_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> 
0

將加入這個模板幫助:

<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>