开发者

Adding a Parent tag to existing elements?

Is there a way to add a parent tag to an existing set of nodes?

Example:

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

Desired output:

   <root>
   <c>
      <d></d>
    <e>
      <f></f>
    </e>
    <a>
开发者_如何学编程    <b></b>
    <b></b>
    <b></b>
    </a>
</c>
    </root>

Thanks!


@empo's answer only works in very simple cases and not with an XML document like this:

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

Here, if we want to wrap every group of consecutive bs within an a, one way to achieve this is:

<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>

when this transformation is applied on the above XML document, the wanted correct result (all groups of consecutive bs are wrapped in an a) is produced:

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


Hopefully your XML now reflects much better your real case, you can use:

<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>


You could use an identity transform and do this:

  <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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜