如何使用xslt将第二个位置的节点添加到根节点

时间:2013-02-13 11:58:30

标签: xslt

我有一个带有动态根元素(不是静态名称)的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>

2 个答案:

答案 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属性。