更改XML属性的值会删除其他属性

时间:2017-12-18 18:32:45

标签: xml xslt xpath

我根据StackOverflow上有关修改XML属性值的各种问题创建了一个简单的XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*" />
    </xsl:copy>
</xsl:template>
<xsl:template match="@Name[.='Source']">
    <xsl:attribute name="Id">MROClass</xsl:attribute>
</xsl:template>

我将它应用于以下XML:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="TARGETDIR">
            <Directory Id="dirD33FABDFBCD72FAC87416BC87B4323D1" Name="Source" />
        </DirectoryRef>
    </Fragment>
</Wix>

问题是修改了Id属性,但删除了Name属性。如何修改单个属性而不删除其他属性?我尝试过使用复制和其他方法,但结果总是一样的。

示例输出:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
        <DirectoryRef Id="TARGETDIR">
            <Directory Id="MROClass" />
        </DirectoryRef>
    </Fragment>
</Wix>

2 个答案:

答案 0 :(得分:1)

Name属性已删除,因为这就是您要匹配的内容。

如果您要更新Id属性,但要根据Name属性,请尝试更改:

match="@Name[.='Source']"

为:

match="*[@Name='Source']/@Id"

答案 1 :(得分:1)

只需添加以下内容,即可在匹配模板的当前上下文中复制原始值。现在,您只需使用新的 Id 属性完全重写 Name 属性。

<xsl:copy-of select="."/>

富勒版:

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

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

  <xsl:template match="@Name[.='Source']">
    <xsl:attribute name="Id">MROClass</xsl:attribute>
    <xsl:copy-of select="."/>
  </xsl:template>

</xsl:stylesheet>