Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding a Parent tag to existing elements?

Tags:

xml

xslt

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!

like image 781
DurkD Avatar asked Jul 30 '26 09:07

DurkD


1 Answers

@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>
like image 152
Dimitre Novatchev Avatar answered Aug 01 '26 01:08

Dimitre Novatchev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!