我有一个带有动态根元素(不是静态名称)的xml树以及该根元素下的一些子元素。现在我想用xslt脚本向子节点添加第二个位置的元素。我该怎么办?
实施例: XML:
<root>
<element1>
<element1a>
..
</element1a>
</element1>
<element2 name="exampleName">This is text.</element2>
</root>
应转换为
<root>
<element1>
<element1a>
..
</element1a>
</element1>
<someNewElement>1234</someNewElement>
<element2 name="exampleName">This is text.</element2>
</root>
到目前为止我得到的是以下内容。但是使用该解决方案,节点仅在第一个位置添加。我需要它在第二个位置。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:template match="/">
<xsl:apply-templates select="/*"/>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:element name="newElement">4711</xsl:element>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:2)
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="/*/*[1]">
<xsl:next-match />
<xsl:element name="newElement">4711</xsl:element>
</xsl:template>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这定义了一个模板,该模板匹配文档元素的第一个元素子元素,执行正常的标识模板处理(使用next-match
),然后在其后插入新元素。你也可以做
<xsl:template match="/*/*[2]">
<xsl:element name="newElement">4711</xsl:element>
<xsl:next-match />
</xsl:template>
匹配第二个子节点并在其前面插入元素。如果<root>
只有一个子元素,则两者之间的差异很明显,在这种情况下,/*/*[1]
版本会插入newElement
,但/*/*[2]
则不会。
答案 1 :(得分:1)
这个怎么样:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="/*/*[1]">
<xsl:call-template name="copy" />
<newElement>4711</newElement>
</xsl:template>
<xsl:template match="node() | @*" name="copy">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在样本输入上运行时,会产生:
<root>
<element1>
<element1a>
..
</element1a>
</element1>
<newElement>4711</newElement>
<element2 name="exampleName">This is text.</element2>
</root>
如果您实际使用的是XSLT 2.0,则应该可以使用<xsl:next-match />
代替<xsl:call-template name="copy" />
,并从其他模板中删除name
属性。