我需要复制一棵树。但对于某些节点(其中attr2 =“yyy”),我想制作2份副本:
输入:
<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没有被替换。
到目前为止,我一直试图弄清楚这一点并没有成功。我感谢任何指导我正确方向的帮助。
答案 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>