Search code examples
xslt-grouping

Group XML with multiple childs


Hello all can someone help with xslt? I'm trying to group this xml by a specific node, but I keep running into an issue that doesn't include the nested info under child5... Any help would be appreciated.

This is the starting xml:

<parent>
    <a>1</a>
    <b>
        <b1>
            <b2>data</b2>
        </b1>
    </b>
    <a>1</a>
    <b>
        <b1>
            <b2>data2</b2>
        </b1>
    </b>
</parent>

Desired output would be:

<parent>
    <data>
        <a>1</a>
        <b>
            <b1>
                <b2>data</b2>
            </b1>
        </b>
    </data>
    <data>
        <a>2</a>
        <b>
            <b1>
                <b2>data</b2>
            </b1>
        </b>
    </data>
</parent>

I've tried this, but it changes all the info under b to a string...?

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="parent">
  <parent>
    <xsl:for-each-group select="*" group-starting-with="a">
      <data>
      <xsl:for-each select="current-group()">
        <xsl:copy>
          <xsl:apply-templates/>
        </xsl:copy>
      </xsl:for-each>
      </data>
    </xsl:for-each-group>
  </parent>
</xsl:template>
</xsl:stylesheet>

Solution

  • Inside the grouping it seems you just want to copy the group e.g.

    <xsl:template match="parent">
      <parent>
        <xsl:for-each-group select="*" group-starting-with="a">
          <data>
            <xsl:copy-of select="current-group()"/>
          </data>
        </xsl:for-each-group>
      </parent>
    </xsl:template>
    

    Or set up the identity transformation with a base template and use <xsl:apply-templates select="current-group()"/> instead of the xsl:copy-of.