XSL - 复制树,复制一些节点两次并更改第二个副本中的属性

时间:2013-06-16 15:44:56

标签: xml xslt

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

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

    <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没有被替换。

    到目前为止,我一直试图弄清楚这一点并没有成功。我感谢任何指导我正确方向的帮助。

1 个答案:

答案 0 :(得分:3)

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

试试这个:

<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>