Re: [xsl] HowTo - Nested for-each XSLSort on multi-column display

Subject: Re: [xsl] HowTo - Nested for-each XSLSort on multi-column display
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Tue, 10 Apr 2001 22:38:22 +0100
Hi Jim,

This is an interesting problem because it combines grouping by value
(the Type of the dog) with grouping by position. I think that the
simplest and easiest method is to create an intermediate node set that
holds the elements grouped by value, and then uses a
grouping-by-position method to group by position.

So, you could create a new node tree that contains the grouped DogAge

  <xsl:variable name="grouped-dogages">
     <xsl:for-each select="/Dogs/BreedTypes/Type">
        <xsl:sort select="." />
        <Breed Type="{.}">
                 select="/Dogs/DogName/DogAge[@Type = current()]">
              <xsl:sort select="@PetName" />
              <xsl:copy select="." />

You can access this as a node set using the node-set() extension
function in whatever namespace is supported by the processor you're

        select="exsl:node-set($grouped-dogages)/Breed" />

[Note: The EXSLT namespace very probably won't work yet - substitute
whatever namespace is appropriate for the processor you're using.]

And you can then operate over it just as if the original structure was
grouped. So you make a new table row per Breed element, and within
that apply templates to the odd DogAge elements, with each of those
creating the row including their following siblings, the even ones:

<xsl:template match="Breed">
      <td colspan="4">Breed Type = <xsl:value-of select="@Type" /></td>
      <th>Pet Name</th><th>Age</th>
      <th>Pet Name</th><th>Age</th>
   <xsl:apply-templates select="DogAge[position() mod 2 = 1]" />

<xsl:template match="DogAge">
   <xsl:variable name="next" select="following-sibling::DogAge" />
      <td><xsl:value-of select="@PetName"></td>
      <td><xsl:value-of select="." /></td>
      <td><xsl:value-of select="$next/@PetName" /></td>
      <td><xsl:value-of select="$next" /></td>

It is possible to do it without the intermediate node set (of course),
but it's a lot uglier (let me know if you want to see it). I'm sure
that the XSL WG would be grateful if you sent this to them as an
example use case for the XSLT 2.0 requirements - there are use cases
that show two levels of grouping by value, but not one like this.

I hope that helps anyway,


Jeni Tennison

 XSL-List info and archive:

Current Thread