XSLT 2.0 grouping into several groups

Hi,

A question on XSL-List today asked about grouping single elements into
multiple groups. The example was roughly:

<?xml version="1.0"?>
<data>
<story>
  <story_id>589608</story_id>
  <story_title>It's Only Human Nature</story_title>
  <program_name>Science Show</program_name>
  <transmission_date>20020629</transmission_date>
  <description>What is human nature? Who really knows?</description>
  <subjects>
    <subject>Psychology</subject>
    <subject>Health</subject>
  </subjects>
</story>
<story>
  <story_id>591325</story_id>
  <story_title>Fins responsible for Hyshot crash</story_title>
  <program_name>Science News</program_name>
  <transmission_date>20020627</transmission_date>
  <description>The failure of a set of fins on the launch rocket was likely
to be the cause of the Hyshot scramjet crash in October 2001, according to
the final report of the investigation released last week. The finding
clears the way for a second launch.</description>
  <subjects>
    <subject>Australian</subject>
    <subject>Space</subject>
    <subject>Engineering</subject>
  </subjects>
</story>
<story>
  <story_id>591756</story_id>
  <story_title>Immunisation gets bad rap on internet</story_title>
  <program_name>Science News</program_name>
  <transmission_date>20020627</transmission_date>
  <description>The internet has an abundance of websites that are negative
towards vaccination and tend to rely on unscientific evidence according to
two separate studies published this week.</description>
  <subjects>
    <subject>Australian</subject>
    <subject>Health</subject>
    <subject>Information Technology</subject>
  </subjects>
</story>
</data>

with the output grouping the stories into groups based on the subject.
I don't think that there's an example of this sort in the grouping
requirements in http://www.w3.org/TR/xslt20req and there probably
should be (it doesn't come up a huge amount, but it does on occasion
and it's something that tends to catch people out).

The questioner was having problems because the way people think about
this kind of grouping (grouping stories by subject) isn't the way you
have to do the grouping. In XSLT 2.0, people's first guess (by
extension from grouping by single values) would be:

  <xsl:for-each-group select="story" group-by="subjects/subject">
    ...
    <xsl:for-each select="current-group()">
      ...
    </xsl:for-each>
    ...
  </xsl:for-each-group>

But as you know, the way xsl:for-each-group works, each story has to
belong to a single group, so you actually have to do:

  <xsl:for-each-group select="story/subjects/subject" group-by=".">
    ...
    <xsl:for-each select="current-group()/ancestor::story">
      ...
    </xsl:for-each>
    ...
  </xsl:for-each-group>

I wonder if the definition of xsl:for-each-group could be changed so
that the natural/intuitive method would actually work. Perhaps, if the
grouping key is a sequence, the item could be added to each group
corresponding to a value in that sequence. I think that then, to get
hold of the particular grouping key value that was being used for a
particular group, there would have to be another function such as
current-group-value(). In other words, you would do:

  <xsl:for-each-group select="story" group-by="subjects/subject">
    Subject: <xsl:value-of select="current-group-value()" />
    <xsl:for-each select="current-group()">
      Title: <xsl:value-of select="story_title" />
    </xsl:for-each>
  </xsl:for-each-group>

The same kind of change doesn't make sense for group-adjacent or
group-starting/ending-with, of course.

If a change like this isn't made, it might be an idea to include an
example along these lines in the spec, so that people can see how to
deal with it.
  
Cheers,

Jeni
---
Jeni Tennison
http://www.jenitennison.com/

Received on Tuesday, 16 July 2002 05:02:24 UTC