我一直在尝试复制节点并更改其属性。基本上,我希望<parent id="1">
也有一个<child id="3">
并在其中添加一个属性,在本文档中:
<container>
<parent id="1">
<child id="1"/>
<child id="2"/>
</parent>
<parent id="2">
<child id="1"/>
<child id="2"/>
<child id="3" attrs="I am special"/>
</parent>
</container>
生成的文档如下所示:
<container>
<parent id="1">
<child id="1"/>
<child id="2"/>
<child id="3" attrs="I am special" cloned="I have been cloned"/>
</parent>
<parent id="2">
<child id="1"/>
<child id="2"/>
<child id="3" attrs="I am special"/>
</parent>
</container>
要复制孩子,我只需选择我想要填充的parent
和apply-templates
以及他想要的对象:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes"/>
<!-- copy everything verbatim -->
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="parent[@id='1']/child[last()]">
<xsl:call-template name="identity"/>
<xsl:apply-templates select="//*/child[@id='3']"/>
</xsl:template>
</xsl:stylesheet>
随着副本的处理,我一直试图改变属性,但无济于事。没有任何内容匹配,并且未使用以下模板添加该属性:
<xsl:template match="child[@id='3' and ../@id='1']">
<xsl:apply-templates select="@*|node()" />
<xsl:attribute name="clone">I have been cloned</xsl:attribute>
</xsl:template>
由于我对XSLT的理解有限,这将在apply-templates
期间触发,本来会复制节点并添加我的属性。输出另有说明:child id="3"
被复制,但没有属性的标志。
我想也许新添加的节点还没有“可访问”,或类似的东西,但是一个简单的规则会匹配它(这不好,因为它修改了我正在复制的原始节点):
<xsl:template match="child[@id='3']">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
<xsl:attribute name="att1">I have been cloned?!</xsl:attribute>
</xsl:copy>
</xsl:template>
我以为我可能一直在弄乱谓词,但添加一个带有类似谓词的属性(减去前一个副本)就像一个魅力:
<xsl:template match="child[@id='1' and ../@id='1']">
<xsl:copy>
<xsl:attribute name="clone">Nope, just a normal kid</xsl:attribute>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
我还认为我的“复制”模板可能与更高的优先级匹配,但是优先级的播放也无济于事。
我错过了什么吗?
答案 0 :(得分:1)
新元素是结果树的一部分,您无法在同一转换步骤中匹配它。我建议使用一种模式来改变要添加的元素的处理:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="@*|node()" mode="#all">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="parent[@id='1']/child[last()]">
<xsl:next-match/>
<xsl:apply-templates select="//*/child[@id='3']" mode="add-att"/>
</xsl:template>
<xsl:template match="child[@id='3']" mode="add-att">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="att1">I have been cloned?!</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:transform>