xsl-list
[Top] [All Lists]

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

2009-04-24 12:22:26
At 2009-04-24 18:04 +0200, Leo Studer wrote:
I am using Saxon-SA9.1.0.6 to transform the following XML file:
...
with the stylesheet
...
    <xsl:function name="my:MakeTableRow">
        <xsl:param name="team"/>
        <xsl:param name="matches"/>
        <tr>
...
        </tr>
    </xsl:function>
...
            <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>

Note you could have just said the following without creating the variable, though I suppose some processors would optimize that out:

<xsl:copy-of select="my:MakeTableRow(current-grouping-key(),current-group())"/>

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?

In one pass you would need to recalculate the 8th column for each entry in the group.

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>

Interesting ... with just a quick review, I suppose you are doing that recalculation since you are returning the row and indexing off of the 8th column, so I am unsure why the above does not work for you.

Any suggestions?

Create the rows and then sort them:

  <xsl:variable name="rows" as="element(tr)+">
    <xsl:for-each-group select="/results/match" group-by="team">
      <xsl:copy-of
   select="my:MakeTableRow(current-grouping- key(),current-group())"/>
    </xsl:for-each-group>
  </xsl:variable>
  <xsl:for-each select="$rows">
     <xsl:sort select="td[8]"/>
     <xsl:copy-of select="."/>
  </xsl:for-each>

That way you aren't doing the complicated row building twice, only once, and the second pass is a simple copy of nodes.

I think you might find that better than trying to find out why rebuilding the row for the sort criteria isn't working for you.

I hope this helps.

. . . . . . . . . Ken

p.s. just before hitting "send" I see David has quickly determined it was a namespace problem, so the above would be modified along the lines of:

  <xsl:variable name="rows" as="element(xhtml:tr)+">
    <xsl:for-each-group select="/results/match" group-by="team">
      <xsl:copy-of
   select="my:MakeTableRow(current-grouping- key(),current-group())"/>
    </xsl:for-each-group>
  </xsl:variable>
  <xsl:for-each select="$rows">
     <xsl:sort select="xhtml:td[8]"/>
     <xsl:copy-of select="."/>
  </xsl:for-each>


--
XSLT/XSL-FO/XQuery hands-on training - Los Angeles, USA 2009-06-08
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
Video lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
Video overview:  http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
G. Ken Holman                 mailto:gkholman(_at_)CraneSoftwrights(_dot_)com
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal


--~------------------------------------------------------------------
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>
--~--