RE: Grouping

One way of meeting this requirement is to use two nested xsl:for-each-group
instructions:
 
<xsl:for-each-group select="os/o" group-by="@a">
  <xsl:for-each-group select="current-group()" group-by="@b">
      <tr>
         <td>
            <xsl:value-of select="current-group()/@id" separator=", "/>
         </td>
      </tr>
   </xsl:for-each-group>
 </xsl:for-each-group>
 
Whether you think this is preferable to the solution using concat() is
largely a matter of personal taste; but it seems difficult to justify
additional syntax to meet this requirement when a solution is already
available.
 
Issue 54 is unrelated, it is concerned with how one decides whether two
grouping keys are equal, for example do "Smith" and "SMITH" go in the same
group? XSLT 2.0 and XPath 2.0 will allow the use of user-selected collations
in all contexts where strings need to be compared.
 
Michael Kay


-----Original Message-----
From: Jeff Yemin [mailto:jeffx@thinkshare.com] 
Sent: 01 August 2002 17:43
To: public-qt-comments@w3.org
Cc: me
Subject: Grouping


I have a question about grouping in the working draft.  We have some
customer use cases where we need to group by multiple criteria, say the
values of multiple attributes instead of just one.  Here's an example:
 
Source XML document:

<os>
   <o id= 'Bif' a='1' b='1' />
   <o id= 'Bay' a='1' b='1' />
   <o id= 'Bob' a='1' b='2' />
   <o id= 'May' a='2' b='1' />
   <o id= 'Moe' a='2' b='1' />
   <o id= 'Mel' a='2' b='2' />
   <o id= 'Joe' a='3' b='2' />
   <o id= 'Sue' a='4' b='1' />
<os>

Desired output:
 
    <table>
      <tr>
        <td>Bif, Bay</td>
      </tr>
      <tr>
        <td>Bob</td>
      </tr>
      <tr>
        <td>May, Moe</td>
      </tr>
      <tr>
        <td>Mel</td>
      </tr>
      <tr>
        <td>Joe</td>
      </tr>
      <tr>
        <td>Sue</td>
      </tr>
    </table>

The best solution we could come up with:


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

   <xsl:for-each-group select="os/o" group-by="concat(@a, ',', @b">

      <tr>

         <td>

            <xsl:value-of select="current-group()/@id" separator=", "/>

         </td>

      </tr>
   </xsl:for-each-group>

</table>

I'm not too happy with having to use concat to generate a group, as it's
difficult to optimize and somewhat unintuitive.  I'd like to see something
more like this:
 

<xsl:sort-key name="o-sort">
  <xsl:sort select="@a"/>
  <xsl:sort select="@b"/>


</xsl:sort-key>
<table xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:for-each-group select="os/o" group-by-sort-key="o-sort">

      <tr>

         <td>

            <xsl:value-of select="current-group()/@id" separator=", "/>

         </td>

      </tr>
   </xsl:for-each-group>

</table>
The semantics would be that the processor would use the named sort key to
group the nodes into a set of equivalence classes.   Each set of nodes for
which all the sort keys compare equal will define a group.  The advantage of
this approach is that the second sort key does not have to be used for nodes
that are already unique under the first sort key.  In this small of an
example it wouldn't matter, but you could imagine larger documents in which
it would make a difference, especially if the select on the second sort key
was a more complicated expression.
 
Perhaps this is what the committee was thinking of with Issue 54 in the 2.0
working draft?  It wasn't clear to me what exactly was being addressed
there.
 
 
Thanks,
 
Jeff Yemin
Thinkshare Corporation

Received on Friday, 2 August 2002 02:12:14 UTC