XSLT 使用条件更改特定元素的属性值

XSLT Change attribute value of specific elements with a condition

我有以下XML内容:

<fragment>
  <directory Id="dirABC" Name="ABC">
    <component Id="cmpA" Guid="*">
      <file Id="filA" KeyPath="yes" Source="SourceRootDir\AAA.exe" />
    </component>
    <component Id="cmpB" Guid="*">
      <file Id="filB" KeyPath="yes" Source="SourceRootDir\BBB.exe" />
    </component>
    <component Id="cmpC" Guid="*">
      <file Id="filC" KeyPath="yes" Source="SourceRootDir\CCC.exe" />
    </component>
  </directory>
</fragment>

我正在尝试查找 Source 属性以 'BBB.exe' 结尾的文件元素,并将其 Id 属性替换为另一个值,例如与 filNEW。在我的示例中,Id 属性值 'filB' 应更改为 'filNEW'。所以,我的 XSLT 定义如下:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
  <xsl:output omit-xml-declaration="no" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/fragment/directory/component/file[substring(@Source, string-length(@Source) - string-length('BBB.exe') + 1)  = 'BBB.exe']">
      <xsl:attribute name="Id">filNEW</xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

但是,结果不是只更新第二个组件元素的文件元素的 Id 属性,而是删除了第二个组件的整个文件元素,并将组件元素的 Id 属性值替换为新的 filNEW 值.当前结果。

<?xml version="1.0" encoding="UTF-8"?>
<fragment>
   <directory Id="dirABC" Name="ABC">
      <component Guid="*" Id="cmpA">
         <file Id="filA" KeyPath="yes" Source="SourceRootDir\AAA.exe"/>
      </component>
      <component Guid="*" Id="filNEW"/>
      <component Guid="*" Id="cmpC">
         <file Id="filC" KeyPath="yes" Source="SourceRootDir\CCC.exe"/>
      </component>
   </directory>
</fragment>

然而,我正试图得到这个结果:

<?xml version="1.0" encoding="UTF-8"?>
<fragment>
   <directory Id="dirABC" Name="ABC">
      <component Guid="*" Id="cmpA">
         <file Id="filA" KeyPath="yes" Source="SourceRootDir\AAA.exe"/>
      </component>
      <component Id="cmpB" Guid="*">
        <file Id="filNEW" KeyPath="yes" Source="SourceRootDir\BBB.exe" />
      </component>
      <component Guid="*" Id="cmpC">
         <file Id="filC" KeyPath="yes" Source="SourceRootDir\CCC.exe"/>
      </component>
   </directory>
</fragment>

我在 XSLT 中做错了什么?

您正在匹配 file 元素,然后生成一个属性。如果您只想替换 @Id 属性的值,则通过在 file 的谓词之后添加 /@Id 来更改您的匹配表达式以匹配 @Id

<xsl:template match="/fragment/directory/component/file[substring(@Source, string-length(@Source) - string-length('BBB.exe') + 1)  = 'BBB.exe']/@Id">
  <xsl:attribute name="Id">filNEW</xsl:attribute>
</xsl:template>