1

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

2 回答 2

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]版本会插入 thenewElement/*/*[2]不会。

于 2013-02-13T12:05:02.773 回答
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属性。

于 2013-02-13T12:08:03.033 回答