XSLT - 属性更改(正则表达式?)

时间:2015-04-12 11:51:21

标签: xslt

我正在尝试使用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,因此无法进行简单的硬编码常量替换。

谢谢

2 个答案:

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