复制并更新输出 xml 树?

Copy with update to output xml tree?

输入文件“in.xml”:

<x1 attr1="1">
  <A default="dA" title="XXX">
    <x2 attr2="2">
      <B default="dB" description="YYY">
        <x3 attr3="3">
          <C default="dC" title="ZZZ"/>
        </x3>
      </B>
    </x2>
  </A>
</x1>

从中获取更新的“updates.xml”文件 - 标记属性 a、b、c:

<Macro>
  <Item key="Element">
    <A title="titleA" description="descriptionA" />
    <B title="titleB" description="descriptionB" />
    <C title="titleC" description="descriptionC" />
  </Item>
</Macro>

输入文件被原封不动地复制到输出树中,添加了“updates.xml”文件中但不在输入文件中的属性。如果标签在输入文件和“updates.xml”文件中具有相同的属性,则输入文件中的数据优先。 XSLT1.0 转换后的文件应该是这样的:

<x1 attr1="1">
  <A default="dA" title="XXX" description="descriptionA">
    <x2 attr2="2">
      <B default="dB" title="titleB" description="YYY">
        <x3 attr3="3">
          <C default="dC" title="ZZZ" description="descriptionC" />
        </x3>
      </B>
    </x2>
  </A>
</x1>

现在这是 XSLT1.0 转换文件:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exslt="http://exslt.org/common"
  exclude-result-prefixes="exslt" version="1.0">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  <xsl:strip-space  elements="*"/>
 
  <xsl:output method="xml" indent="yes" />
  <xsl:variable name="update" select="document('update.xml')"/>
 
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
 
  <xsl:template match="*">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:variable name="name" select="name()"/>
      <xsl:apply-templates select="$update//*[name(.) = $name]/@*"/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
 
</xsl:stylesheet>

当前XML转换后的文件:

<x1 attr1="1">
  <A default="dA" title="titleA" description="descriptionA">
    <x2 attr2="2">
      <B default="dB" title="titleB" description="descriptionB">
        <x3 attr3="3">
          <C default="dC" title="titleC" description="descriptionC" />
        </x3>
      </B>
    </x2>
  </A>
</x1>

如何在不更改的情况下复制输入文件中存在的所有属性?

更改

的顺序
  <xsl:apply-templates select="@*"/>
  <xsl:variable name="name" select="name()"/>
  <xsl:apply-templates select="$update//*[name(.) = $name]/@*"/>

  <xsl:variable name="name" select="name()"/>
  <xsl:apply-templates select="$update//*[name(.) = $name]/@*"/>
  <xsl:apply-templates select="@*"/>

这样输入文档中的属性“获胜”,因为它们是最后复制的。