Sandeep Singh wrote:
How to do group by in XSLT ?
With XSLT 2.0 you use xsl:for-each-group and current-group() and
current-grouping-key(), with XSLT 1.0 you use Muenchian grouping.
XSLT 2.0 is currently supported by Saxon 9 from
http://saxon.sourceforge.net/ which has Java and .NET versions and
interfaces, by AltovaXML tools
http://www.altova.com/altovaxml.html and
by Gestalt
http://gestalt.sourceforge.net/.
With XSLT 1.0 as supported by MSXML 3, 4, 5, 6 and XslTransform and
XslCompiledTransform and Firefox and Opera 9 and Safari (and lots of
others) you use Muenchian grouping, see
http://www.jenitennison.com/xslt/grouping/index.xml
I tried on the following codes:
<files>
<file name="swablr.eps" size="4313" project="mars"/>
<file name="batboy.wks" size="424" project="neptune"/>
<file name="potrzebie.dbf" size="1102" project="jupiter"/>
<file name="kwatz.xom" size="43" project="jupiter"/>
<file name="paisley.doc" size="988" project="neptune"/>
<file name="ummagumma.zip" size="2441" project="mars"/>
<file name="schtroumpf.txt" size="389" project="mars"/>
<file name="mondegreen.doc" size="1993" project="neptune"/>
<file name="gadabout.pas" size="685" project="jupiter"/>
</files>
<xsl:template match="files">
<xsl:for-each-group select="file" group-by="@project">
<!-some code-->
</xsl:for-each-group>
</xsl:template>
but it gives a sentax error
'xsl:for-each-group ' can not be a child of 'files' element.
Which XSLT processor do you use? See above for a list of processors
which support xsl:for-each-group.
Here is an example using Muenchian grouping with XSLT 1.0:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="by-project" match="file" use="@project"/>
<xsl:output method="text"/>
<xsl:template match="files">
<xsl:apply-templates select="file[generate-id() =
generate-id(key('by-project', @project)[1])]"/>
</xsl:template>
<xsl:template match="file">
<xsl:value-of select="concat(@project, ': ')"/>
<xsl:for-each select="key('by-project', @project)">
<xsl:value-of select="@name"/>
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
<xsl:value-of select="'
'"/>
</xsl:template>
</xsl:stylesheet>
Text output is:
mars: swablr.eps, ummagumma.zip, schtroumpf.txt
neptune: batboy.wks, paisley.doc, mondegreen.doc
jupiter: potrzebie.dbf, kwatz.xom, gadabout.pas
The same result achieved can be achieved with XSLT 2.0:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text"/>
<xsl:template match="files">
<xsl:for-each-group select="file" group-by="@project">
<xsl:value-of select="concat(@project, ': ')"/>
<xsl:value-of select="current-group()/@name" separator=", "/>
<xsl:value-of select="'
'"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
--
Martin Honnen --- MVP XML
http://JavaScript.FAQTs.com/