RE: [xsl] XSLT2 grouping over multiple documents

Subject: RE: [xsl] XSLT2 grouping over multiple documents
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Thu, 23 Jun 2005 08:47:31 +0100
You don't actually need to make copies of all the documents before grouping
them. Just do

<xsl:for-each-group select="document(a/@href)/responses/response"
    group-by="@for">

To sort the groups according to the number of correct answers, put an
xsl:sort as the first child of xsl:for-each-group, thus:

  <xsl:sort select="count(current-group()[@correct='correct'])"/>

The inner loop:

<xsl:for-each-group select="current-group()"
> group-by="@correct">
>               <xsl:value-of select="count(current-group())" />
>             </xsl:for-each-group>

is interesting because a selected element doesn't get put in a group if the
grouping key evaluates to an empty sequence. So it seems there will only be
one group coming out of this, the group that has @correct='correct'. So this
loop seems unnecessary, it is equivalent to

<xsl:value-of select="count(current-group()[@correct='correct'])"/>

Michael Kay
http://www.saxonica.com/

 

> -----Original Message-----
> From: Thomas J. Sebestyen [mailto:a9105535@xxxxxxxxxxxxxxxxx] 
> Sent: 23 June 2005 00:50
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] XSLT2 grouping over multiple documents
> 
> Hello,
> 
> I have a couple of xml-documents, all with the same structure:
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <responses>
> 	<response for="js0" correct="correct">C</response>
> 	<response for="js1">A</response>
> 	<response for="js2" correct="correct">A</answer>
> 	<response for="db0" correct="correct">A</response>
> 	<response for="db1">B</response>
>  ...
> </responses>
> 
> 
> I use an xml-file to collect all this documents:
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <alldocs>
> 	<a href="184855.xml" />
> 	<a href="190026.xml" />
>  ...
> </alldocs>
> 
> I woul like to group all <response> by  @for over all 
> documents and then
> count how many from them has an @correct.
> My solution is the following (which works for me):
> 
> <?xml version="1.0" encoding="iso-8859-1"?>
> <xsl:stylesheet version="2.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>   <xsl:output method="html" indent="yes" encoding="iso-8859-1" />
>   <xsl:template match="/alldocs">
>     <xsl:variable name="alldocs">
>       <xsl:for-each select="document(a/@href)">
>         <xsl:copy-of select="/responses/response" />
>       </xsl:for-each>
>     </xsl:variable>
>     <html>
>       <head><title>Responses</title></head>    
>       <body>
>         <xsl:for-each-group select="$alldocs/response" 
> group-by="@for">
>           <p>
>             <b><xsl:value-of select="current-grouping-key()" />=</b>
>             <xsl:for-each-group select="current-group()"
> group-by="@correct">
>               <xsl:value-of select="count(current-group())" />
>             </xsl:for-each-group>
>           </p>
>         </xsl:for-each-group>
>       </body>
>     </html>
>   </xsl:template>
> </xsl:stylesheet>
> 
> Is there a better solution?
> (for exmaple if I would like to sort the output by the number of
> @corrects)
> 
> Regards
> Thomas

Current Thread