xsl-list
[Top] [All Lists]

[xsl] How to sort by elements of a function output?

2009-04-24 12:05:32
Hello

I am using Saxon-SA9.1.0.6 to transform the following XML file:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="results1.xsl"?>

<results>
    <match date="1998-06-10">
        <team score="2">Brazil</team>
        <team score="1">Scotland</team>
    </match>
    <match date="1998-06-10">
        <team score="2">Morocco</team>
        <team score="2">Norway</team>
    </match>
    <match date="1998-06-16">
        <team score="1">Scotland</team>
        <team score="1">Norway</team>
    </match>
    <match date="1998-06-16">
        <team score="3">Brazil</team>
        <team score="0">Morocco</team>
    </match>
    <match date="1998-06-23">
        <team score="1">Brazil</team>
        <team score="2">Norway</team>
    </match>
    <match date="1998-06-23">
        <team score="0">Scotland</team>
        <team score="3">Morocco</team>
    </match>
</results>


with the stylesheet


<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform "
    xmlns:fn="http://www.w3.org/2005/xpath-functions";
    xmlns:xs="http://www.w3.org/2001/XMLSchema";
    xmlns:my="http://leostuder.ch";
    xmlns="http://www.w3.org/1999/xhtml";
    exclude-result-prefixes="fn xs my">

    <xsl:output method="xhtml" encoding="ISO-8859-1" indent="yes"
        doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd "/>

    <xsl:import-schema namespace="http://www.w3.org/1999/xhtml";
schema-location="http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd "/>

    <xsl:function name="my:MakeTableRow">
        <xsl:param name="team"/>
        <xsl:param name="matches"/>
        <tr>
            <td>
                <xsl:value-of select="$team"/>
            </td>
            <td>
                <xsl:value-of select="fn:count($matches)"/>
            </td>
            <xsl:variable name="won"
select="fn:count($matches[team[.=$team]/@score gt team[.!=$team]/@score])"
                as="xs:integer"/>
            <td>
                <xsl:value-of select="$won"/>
            </td>
            <td>
                <xsl:value-of
select="fn:count($matches[team[.=$team]/@score lt team[.!=$team]/@score])"/>
            </td>
            <xsl:variable name="drawn"
select="fn:count($matches[team[.=$team]/@score eq team[.!=$team]/@score])"
                as="xs:integer"/>
            <td>
                <xsl:value-of select="$drawn"/>
            </td>
            <td>
<xsl:value-of select="fn:sum($matches/team[.=$team]/ @score)"/>
            </td>
            <td>
<xsl:value-of select="fn:sum($matches/team[.!=$team]/ @score)"/>
            </td>
            <td>
                <xsl:value-of select="3*$won+$drawn"/>
            </td>
        </tr>
    </xsl:function>

    <xsl:template match="/">
        <html xsl:validation="strict">
            <head>
                <title>Spielresultate</title>
            </head>
            <body>
                <xsl:apply-templates/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="results">
        <h2>Results</h2>

        <table cellpadding="10">
            <thead>
                <tr>
                    <td>Team</td>
                    <td>Played</td>
                    <td>Won</td>
                    <td>Lost</td>
                    <td>Drawn</td>
                    <td>For</td>
                    <td>Against</td>
                    <td>Points</td>
                </tr>
            </thead>

<xsl:for-each-group select="/results/match" group- by="team"> <xsl:variable name="tableRow" select="my:MakeTableRow(current-grouping-key(),current-group())"/>
                <xsl:copy-of select="$tableRow"/>
            </xsl:for-each-group>

        </table>

    </xsl:template>

</xsl:stylesheet>



In the tag <xsl:for-each-group select="/results/match" group-by="team">
I would like to sort the outcome by the $tableRow/td[8] contents (i.e. the points) .
How do I do that?

The approach

           <xsl:for-each-group select="/results/match" group-by="team">
<xsl:sort select="my:MakeTableRow(current-grouping- key(),current-group())/td[8]"
                    order="descending"/>
<xsl:copy-of select="my:MakeTableRow(current-grouping- key(),current-group())"/>
            </xsl:for-each-group>

does not do the job, no error however. Calling the function my:MakeTableRow twice seems also quite off...

Any suggestions?

Thanks in advance
Leo







--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--