1

I have to regroup the xml elements in the same xml structure based on the attributes I have an xml like this

<a>
    <b>
        <c>
            <d1 att2="t1">test 1</d1>
            <d1>test 2</d1>
            <d1>test 3</d1>
            <d1 att2="t1">test 4</d1>
        </c>
    </b>
</a>

I need to conver this xml to,

<a>
    <b>
        <c>
            <d1 att2="t1">test 1</d1>
            <d1 att2="t1">test 4</d1>
        </c>
    </b>
</a>
<a>
    <b>
        <c>
            <d1>test 2</d1>
        </c>
    </b>
</a>
<a>
    <b>
        <c>
            <d1>test 3</d1>
        </c>
    </b>
</a>
StuartLC
  • 104,537
  • 17
  • 209
  • 285
chavsh
  • 11
  • 2
  • To confirm, if `att2` is the same, then group them, but if it is different or missing, then new group? Do you access to an xslt 2 processor? Please tag as such? – StuartLC Dec 04 '14 at 18:16
  • @StuartLC your assumption is correct and I have access to xslt 2 processor. – chavsh Dec 04 '14 at 18:26

1 Answers1

0

This is a really uninspired / manual effort, but seems to get the job done. The template applies separate branches to elements with and without @att2 attributes.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/">
        <root>
            <xsl:for-each-group select="//d1[@att2]" group-by="@att2">
                <a>
                    <b>
                        <c>
                            <xsl:for-each select="current-group()">
                                <xsl:apply-templates select="." mode="nowrapper"></xsl:apply-templates>
                            </xsl:for-each>
                        </c>
                    </b>
                </a>
            </xsl:for-each-group>
            <xsl:apply-templates select="//d1[not(@att2)]" mode="wrapper" />
        </root>
    </xsl:template>

    <xsl:template match="d1" mode="wrapper">
        <a>
            <b>
                <c>
                    <xsl:apply-templates select="." mode="nowrapper" />
                </c>
            </b>
        </a>
    </xsl:template>

    <xsl:template match="d1" mode="nowrapper">
        <xsl:copy-of select="." />
    </xsl:template>

</xsl:stylesheet>
StuartLC
  • 104,537
  • 17
  • 209
  • 285