将父标记添加到现有元素?

时间:2011-09-09 13:33:34

标签: xml xslt

有没有办法将父标记添加到现有节点集?

示例:

<root>
<c>
  <d></d>
<e>
  <f></f>
</e>
<b></b>
<b></b>
<b></b>
</c>
</root>

期望的输出:

   <root>
   <c>
      <d></d>
    <e>
      <f></f>
    </e>
    <a>
    <b></b>
    <b></b>
    <b></b>
    </a>
</c>
    </root>

谢谢!

3 个答案:

答案 0 :(得分:3)

@ empo的答案仅适用于非常简单的情况,而不适用于这样的XML文档

<root>
    <c>
        <d></d>
        <e>
            <f></f>
        </e>
        <b></b>
        <b></b>
        <b></b>
    </c>
    <b></b>
    <b></b>
</root>

在这里,如果我们想在b中包含连续a的每个组,实现此目的的一种方法是:< / p>

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <xsl:key name="kFollowing" match="b"
  use="generate-id(preceding-sibling::*[not(self::b)][1])"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="b[not(preceding-sibling::*[1][self::b])]">
  <a>
   <xsl:copy-of select=
   "key('kFollowing', generate-id(preceding-sibling::*[1]))"/>
  </a>
 </xsl:template>
 <xsl:template match="b"/>
</xsl:stylesheet>

当对上述XML文档应用此转换时,生成所需的正确结果(所有连续的b组包含在a中):< / p>

<root>
   <c>
      <d/>
      <e>
         <f/>
      </e>
      <a>
         <b/>
         <b/>
         <b/>
      </a>
   </c>
   <a>
      <b/>
      <b/>
   </a>
</root>

答案 1 :(得分:2)

希望您的XML现在能够更好地反映您的实际情况,您可以使用:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="root/c/b[1]">
        <a>
            <xsl:copy-of select="self::*|following::b"/>
        </a>
    </xsl:template>

    <xsl:template match="b"/>

</xsl:stylesheet>

答案 2 :(得分:1)

您可以使用身份转换并执行此操作:

  <xsl:template match="root">
    <root>
      <a>
        <xsl:apply-templates/>
      </a>
    </root>
  </xsl:template>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>