2

我需要复制一棵树。但对于某些节点(其中 attr2="yyy")我想制作 2 个副本:

  1. 第一个“原样”
  2. 第二个修改 attr2 值。

输入:

<root>
    <element>
        <node1 attr1="xxx">copy once</node1>
        <node2 attr2="yyy">copy twice, modify attr2 in 2nd copy</node2>
        <node3 attr2="yyy" attr3="zzz">copy twice, modify attr2 in 2nd copy</node3>
    </element>
</root>

期望的输出:

<root>
    <element>
        <node1 attr1="xxx">copy once</node1>
        <node2 attr2="yyy">copy twice, modify attr2 in 2nd copy</node2>
        <node2 attr2="changed">copy twice, modify attr2 in 2nd copy</node2>
        <node3 attr2="yyy" attr3="zzz">copy twice, modify attr2 in 2nd copy</node3>
        <node3 attr2="changed" attr3="zzz">copy twice, modify attr2 in 2nd copy</node3>
    </element>
</root>

我正在使用这个样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="node()[@attr2='yyy']">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
        <xsl:copy>
            <xsl:attribute name="attr2">changed</xsl:attribute>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

并获得以下输出:

<root>
    <element>
        <node1 attr1="xxx">copy once</node1>
        <node2 attr2="yyy">copy twice, modify attr2 in 2nd copy</node2>
        <node2 attr2="changed">copy twice, modify attr2 in 2nd copy</node2>
        <node3 attr2="yyy" attr3="zzz">copy twice, modify attr2 in 2nd copy</node3>
        <node3 attr2="changed">copy twice, modify attr2 in 2nd copy</node3>
    </element>
</root>

请注意,在 node3 的第二个副本中缺少 attr3。如果我修改要应用于节点和属性的第二个模板:

<xsl:copy>
    <xsl:attribute name="attr2">changed</xsl:attribute>
    <xsl:apply-templates select="node()|@*"/>
</xsl:copy>

然后 attr2 不会被替换。

到目前为止,我一直试图自己解决这个问题,但没有成功。我很感激任何帮助指出我正确的方向。

4

1 回答 1

3

你很接近。只有一个留置权丢失。 在更改 attr2 内容之前
添加一行以复制所有属性 。<xsl:apply-templates select="@*"/>

尝试这个:

<xsl:template match="node()[@attr2='yyy']">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:attribute name="attr2">changed</xsl:attribute>
        <xsl:apply-templates />
    </xsl:copy>
</xsl:template>
于 2013-06-16T16:22:03.623 回答