Search

Haloo,

I've been building a table of data with stats of points scored in rugby matches and have come up against something I'm not quite sure how to tackle in XSLT:

   <xsl:template match="matches/player-name" mode="overview">
 <xsl:variable name="tries" select="sum(entry/tries)"/>
 <xsl:variable name="conversions" select="sum(entry/conversions)"/>
 <xsl:variable name="penalties" select="sum(entry/penalties)"/>
 <xsl:variable name="dropgoals" select="sum(entry/drop-goals)"/>
 <xsl:variable name="total" select="($dropgoals * 2) + ($penalties * 3)+ ($conversions * 2) + ($tries * 5)"/>
 <xsl:variable name="sort-order" select="'ascending'"/>

  <tr align="center">
    <td align="left"><a href="{$root}/{$url-language}/{$current-page}/{@link-handle}"><xsl:value-of select="@value"/></a></td>
    <td align="center"><xsl:value-of select="$tries"/></td>
    <td align="center"><xsl:value-of select="sum(entry/conversions)"/></td>
    <td align="center"><xsl:value-of select="sum(entry/penalties)"/></td>
    <td align="center"><xsl:value-of select="sum(entry/drop-goals)"/></td>

    <td align="center"><xsl:value-of select="$total" order="$sort-order"/></td>
  </tr> 

I'm using variables to tot up the totals for the players points and am in need of sorting the data with the highest score first.

Is it not a good idea to do all this in XSLT? and should I be doing it in the section instead using something like reflection field and maybe sort on the value of the reflection field instead maybe?

What is possible with Variable and the xsl:sort function here?

Cheers

xsl:sort is used when you xsl:apply-templates. It accepts a standard select attribute that you can use any xpath in, including variables. IMO you'd be better using parameters in the template though.

As for overhead etc, I'm not too sure myself which would be more beneficial... I'm doing something similar myself, but with a custom DS, so have to sort in xslt.

Ahh right, I'll try and make them into params and apply the sort where I've got the template applied then!

Thanks, just reading a few things about complicated xpath to be able to sort on a variable... :| crazy code and unnecessary me thinks!

It's tricky without seeing your XML, as I'm not sure how your data is structured. It looks like you have:

<matches>
    <player-name>
        <entry />
    </player-name>
</matches>

Which doesn't look like a standard Symphony structure.

I'm going to assume it is actually standard data source output like:

<players>
    <entry>
        <name>Joe Bloggs</name>
        <tries>2</tries>
        <conversions>30</conversions>
    </entry>
</players>

XSLT:

<xsl:template match="data">

    <xsl:apply-templates select="players/entry">
        <xsl:sort select="(drop-goals * 2) + (penalties * 3) + (conversions * 2) + (tries * 5)" data-type="number" order="ascending"/>
    </xsl:apply-templates>

</xsl:template>


<xsl:template select="entry">
    <tr>
        <td><xsl:value-of select="name"/></td>
        <td><xsl:value-of select="drop-goals"/></td>
    </tr>
</xsl:template>

Close?

Oh, I just realised your original XML isn't quite how I envisaged as you're suming the stats for each player. Still, the same principle applies.

Another way that I have used in the past is to cache all your XML into a variable, add a new element for sorting on later, and then iterate over the new XML.

<xsl:variable name="players">
    <xsl:for-each select="/data/players/entry">
        <entry id="{@id}">
            <xsl:attribute name="score">
                <xsl:value-of select="(sum(drop-goals) * 2) + (sum(penalties) * 3) + (sum(conversions) * 2) + (sum(tries) * 5)" />
            </xsl:attribute>
            <xsl:copy-of select="*"/>
        </entry>
    </xsl:for-each>
</xsl:variable>

<xsl:apply-templates select="exsl:node-set($players)/entry">
    <xsl:sort select="@score" data-type="number" order="ascending"/>
</xsl:apply-templates>

Recreate the entries inside a variable, but add a score attribute to each one. You can then iterate over this new node set (because we're using XSLT 1.0 you will need to use the EXSLT node-set function to convert the variable into a proper node set) and sort on that new attribute.

Oh man, thanks Nick, just checked back on this post and read through what you have posted! thanks for this!

I'd already figured I'd sort on the total of (drop-goals * 2) + (penalties * 3) + (conversions * 2) + (tries * 5) before reading this as well.

My XML is grouped by Player-name in the DS output so I do have the player-name node before the entry of each stat in my XML... I was thinking of a means to output the total score for each player in a given season and then I could dial down into their 'per match' scores using url param filters on player name and match ID, so this sorting was a great way to provide the club with a top scorers record.

Now the club has 10 teams - so I need to provide the top 5 scorers for each team in a series of tables.. ohh appy days :) thanks again.

EDIT: Funny enough Nick, I'm using the EXSL function to tally the scores when I filter into each player stat, so I was half way there... learnt something new today! thanks both :)

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details