[xsl] Re:[xsl] both sorting and grouping set of nodes

Subject: [xsl] Re:[xsl] both sorting and grouping set of nodes
From: Markus Flatscher <markus.flatscher@xxxxxxxxx>
Date: Thu, 3 Dec 2009 00:28:02 -0500
Dear Syd,

re Appendix 1: that would have to be the reserved set of names for
2010 North Atlantic storms. I'm glad to hear this is only a dummy
sample set, since you point out you have hundreds of them.

Anyways, taking your own approach as a starting point, I think one way
to do it would be to sort and store the names in a variable prior to
the table transform, as in (B) below.

Hope this helps,

Markus


---
(A) Input
---snip---
<?xml version="1.0" encoding="UTF-8"?>
<names>
    <name>Julia</name>
    <name>Virginie</name>
    <name>Bonnie</name>
    <name>Paula</name>
    <name>Lisa</name>
    <name>Danielle</name>
    <name>Fiona</name>
    <name>Nicole</name>
    <name>Alex</name>
    <name>Shary</name>
    <name>Earl</name>
    <name>Gaston</name>
    <name>Colin</name>
    <name>Matthew</name>
    <name>Hermine</name>
    <name>Igor</name>
    <name>Karl</name>
    <name>Otto</name>
    <name>Richard</name>
    <name>Tomas</name>
    <name>Walter</name>
</names>
---snap---

(B) Transform
---snip---
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="2.0">

    <xsl:template match="/">
        <!-- first, sort data in a variable -->
        <xsl:variable name="sortedNames">
            <names>
                <xsl:for-each select="//name">
                    <xsl:sort select="normalize-space(.)"/>
                    <name>
                        <xsl:apply-templates/>
                    </name>
                </xsl:for-each>
            </names>
        </xsl:variable>

        <!-- then proceed as usual, processing name elements in $sortedNames -->
        <table border="1">
            <xsl:variable name="Q" select="ceiling( count( //name ) div 4 )"/>
            <xsl:for-each select="$sortedNames//name[position() &lt;= $Q]">
                <xsl:variable name="Q1" select="position() + (1 * $Q)"/>
                <xsl:variable name="Q2" select="position() + (2 * $Q)"/>
                <xsl:variable name="Q3" select="position() + (3 * $Q)"/>
                <tr>
                    <td>
                        <xsl:value-of select="normalize-space(.)"/>
                    </td>
                    <td>
                        <xsl:value-of select="normalize-space(
/*//name[ $Q1] )"/>
                    </td>
                    <td>
                        <xsl:value-of select="normalize-space(
/*//name[ $Q2] )"/>
                    </td>
                    <td>
                        <xsl:value-of select="normalize-space(
/*//name[ $Q3] )"/>
                    </td>
                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>
---snap---

(C) Result
---snip---
<table border="1">
    <tr>
        <td>Alex</td>
        <td>Gaston</td>
        <td>Matthew</td>
        <td>Tomas</td>
    </tr>
    <tr>
        <td>Bonnie</td>
        <td>Hermine</td>
        <td>Nicole</td>
        <td>Virginie</td>
    </tr>
    <tr>
        <td>Colin</td>
        <td>Igor</td>
        <td>Otto</td>
        <td>Walter</td>
    </tr>
    <tr>
        <td>Danielle</td>
        <td>Julia</td>
        <td>Paula</td>
        <td/>
    </tr>
    <tr>
        <td>Earl</td>
        <td>Karl</td>
        <td>Richard</td>
        <td/>
    </tr>
    <tr>
        <td>Fiona</td>
        <td>Lisa</td>
        <td>Shary</td>
        <td/>
    </tr>
</table>
---snap---

Current Thread