RE: [xsl] xslt 2.0 grouping; was Dividing a list of nodes into parts of the alphabet

Subject: RE: [xsl] xslt 2.0 grouping; was Dividing a list of nodes into parts of the alphabet
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 3 Dec 2004 11:39:24 -0000
> I found this intriguing... and not exactly clear (to me at least).
>  Test input
> 
> <?xml version="1.0" encoding="UTF-8"?>
>  <categories>
>    <item>
>      <artist>Sbout the Moon</artist>
>      <title>Carved in Stigmata Wounds</title> 
>    </item>
>    <item>
>      <artist>Satyricon</artist>
>      <title>Rebel Extravaganza</title>
>    </item>
>    <item>
>      <artist>Secrets of the Moon</artist>
>      <title>Carved in Stigmata Wounds</title> 
>    </item>
>  </categories>

That's not particularly useful input since all the artists begin with the
same letter, so go in the same group.
>  
> 
> stylesheet:
> 
>   <xsl:template match="/">
>          <xsl:apply-templates/>
>   </xsl:template>
> 
>   <xsl:template match="group"/>

I see no <group> elements in your data...
> 
>   <xsl:template match="categories">
>     <xsl:for-each-group select="item" group-by="f:grouping-key(.)">
>       <xsl:value-of select="substring(artist,1,1)"/>
>     </xsl:for-each-group>
>     <xsl:apply-templates select="item"/>
>   </xsl:template>

Having created the groups, you're not doing much with them! I would expect
to see something like:

<xsl:template match="categories">
     <xsl:for-each-group select="item" group-by="f:grouping-key(.)">
       <page>
       <title><xsl:value-of select="substring(artist,1,1)"/></title>
       <xsl:apply-templates select="current-group()"/>
       </page>
     </xsl:for-each-group>
   </xsl:template>

The apply-templates outside the for-each-group is particulary weird. Why
group the items and then display them ungrouped?
> 
>   <xsl:template match="item">
>       <xsl:message>
>       <xsl:value-of select="f:grouping-key(.)[1]"/>
>     </xsl:message>
>   </xsl:template>

This gives the error

Error at function f:grouping-key() on line 28 of file:/c:/temp/test.xsl:
  An empty sequence is not allowed as the result of function
f:grouping-key()

That's because my code was wrong (type checking is good at catching errors).
If the artist begins with "A", as all yours do, then it doesn't match any of
the ranges. I leave fixing that as an exercise to the reader: I was only
trying to sketch the idea.

(The idea of course is that all the artists whose names are in the range A-G
get the grouping key A, all those in the range H-L get the grouping key H,
and so on. If you want to display the grouping key as a page title, it would
probably be better to compute the grouping key not as "H" but as "H to L",
say. I did a similar exercise recently where we were grouping on numeric
bands, e.g. "from 1 to 10,000", "from 10,001 to 50,000" - it's the only case
I've seen where we wanted to sort the groups on anything other than the
grouping key.).

Michael Kay
http://www.saxonica.com/
> 
> 
> <xsl:function name="f:grouping-key" as="xs:string">
>   <xsl:param name="item" as="element(item)"/>
>   <xsl:variable name="ranges">
>     <range from="A" to="G"/>
>     <range from="H" to="L"/>
>     <range from="M" to= "P"/>
>     <range from="Q" to= "Z"/>
>   </xsl:variable>
>   <xsl:sequence select="$ranges/range 
>      [string(@from) lt substring($item/artist,1,1) and 
>       string(@to) ge substring($item/artist,1,1)]/@from"/>
> </xsl:function>
> 
> 
> Comments:
> 
> 1. If the item/artist are not lexically sequential it bombs.
> 2. I don't understand the grouping, hence the item template,
>    which shows outptu I don't understand either.
> 
> Anyone care to explain further please?
> 
> TIA daveP.
> 
> -- 
> DISCLAIMER:
> 
> NOTICE: The information contained in this email and any 
> attachments is 
> confidential and may be privileged.  If you are not the intended 
> recipient you should not use, disclose, distribute or copy any of the 
> content of it or of any attachment; you are requested to notify the 
> sender immediately of your receipt of the email and then to delete it 
> and any attachments from your system.
> 
> RNIB endeavours to ensure that emails and any attachments generated by
> its staff are free from viruses or other contaminants.  However, it 
> cannot accept any responsibility for any  such which are transmitted.
> We therefore recommend you scan all attachments.
> 
> Please note that the statements and views expressed in this email and 
> any attachments are those of the author and do not 
> necessarily represent
> those of RNIB.
> 
> RNIB Registered Charity Number: 226227
> 
> Website: http://www.rnib.org.uk

Current Thread