How does Muenchian grouping work in details?
I have a simple XML document generated from a database:
<CLIENTS>
<CLIENT>
<NAME>John</NAME>
<ACCOUNT_NUMBER>1424763562761</ACCOUNT_NUMBER>
<LAST_USED>2012-10-03</LAST_USED>
<AMOUNT>5000</AMOUNT>
</CLIENT>
<CLIENT>
<NAME>John</NAME>
<ACCOUNT_NUMBER>543667543732</ACCOUNT_NUMBER>
<LAST_USED>2012-10-02</LAST_USED>
<AMOUNT>10000</AMOUNT>
</CLIENT>
...
I'd like to group by the name node. How can I the desired ouput to be the following?
<ClIENTS>
<CLIENT>
<NAME>John</NAME>
<ACCOUNT>
<ACCOUNT_NUMBER>1424763562761</ACCOUNT_NUMBER>
<LAST_USED>2012-10-03</LAST_USED>
<AMOUNT>5000</AMOUNT>
</ACCOUNT>
<ACCOUNT>
<ACCOUNT_NUMBER>543667543732</ACCOUNT_NUMBER>
<LAST_USED>2012-10-03</LAST_USED>
<AMOUNT>10000</AMOUNT>
</ACCOUNT>
....
</CLIENTS>
Read www.jenitennison.com/xslt/grouping/muenchian.xml, for a help with the code define a key
<xsl:key name="client-by-name" match="CLIENT" use="NAME"/>
then use templates as
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="CLIENTS">
<xsl:copy>
<xsl:apply-templates select="CLIENT[generate-id() = generate-id(key('client-by-name', NAME)[1])]" mode="group"/>
<xsl:copy>
</xsl:template>
<xsl:template match="CLIENT" mode="group">
<xsl:copy>
<xsl:copy-of select="NAME"/>
<xsl:apply-templates select="key('client-by-name', NAME)"/>
</xsl:copy>
</xsl:template>
<xsl:template match="CLIENT">
<ACCOUNT>
<xsl:apply-templates select="node()[not(self::NAME)]"/>
</ACCOUNT>
</xsl:template>
[edit] If you want to use XSLT 2.0 then of course you don't need Muenchian grouping, instead you use
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="CLIENTS">
<xsl:copy>
<xsl:for-each-group select="CLIENT" group-by="NAME">
<CLIENT>
<xsl:apply-templates select="NAME, current-group()"/>
</CLIENT>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="CLIENT">
<ACCOUNT>
<xsl:apply-templates select="node() except NAME"/>
</ACCOUNT>
</xsl:template>