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>
我有以下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>