Grouping in XSLT

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Sandeep Singh

    Grouping in XSLT

    Hi,

    How to do group by in XSLT ?

    I tried on the following codes:

    <files>
    <file name="swablr.ep s" size="4313" project="mars"/>
    <file name="batboy.wk s" size="424" project="neptun e"/>
    <file name="potrzebie .dbf" size="1102" project="jupite r"/>
    <file name="kwatz.xom " size="43" project="jupite r"/>
    <file name="paisley.d oc" size="988" project="neptun e"/>
    <file name="ummagumma .zip" size="2441" project="mars"/>
    <file name="schtroump f.txt" size="389" project="mars"/>
    <file name="mondegree n.doc" size="1993" project="neptun e"/>
    <file name="gadabout. pas" size="685" project="jupite r"/>
    </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.

    Can any one help me out ?

    Thanks in advance.

    Sandy.

    Please reply on the same group.


  • Martin Honnen

    #2
    Re: Grouping in XSLT

    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
    XslCompiledTran sform and Firefox and Opera 9 and Safari (and lots of
    others) you use Muenchian grouping, see

    I tried on the following codes:
    >
    <files>
    <file name="swablr.ep s" size="4313" project="mars"/>
    <file name="batboy.wk s" size="424" project="neptun e"/>
    <file name="potrzebie .dbf" size="1102" project="jupite r"/>
    <file name="kwatz.xom " size="43" project="jupite r"/>
    <file name="paisley.d oc" size="988" project="neptun e"/>
    <file name="ummagumma .zip" size="2441" project="mars"/>
    <file name="schtroump f.txt" size="389" project="mars"/>
    <file name="mondegree n.doc" size="1993" project="neptun e"/>
    <file name="gadabout. pas" size="685" project="jupite r"/>
    </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:styleshe et
    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:styleshe et
    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

    Comment

    Working...