This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Customised sorting
- To: Mille Eriksson <mille dot eriksson at observergroup dot com>
- Subject: Re: [xsl] Customised sorting
- From: Jeni Tennison <mail at jenitennison dot com>
- Date: Thu, 5 Apr 2001 09:40:14 +0100
- CC: XSL-List at lists dot mulberrytech dot com
- Organization: Jeni Tennison Consulting Ltd
- References: <3ACC1F31.C8CDD65D@observergroup.com>
- Reply-To: xsl-list at lists dot mulberrytech dot com
Hi Mille,
> Now, my problem is very similar to this example but with the
> addition that I need to sort the groups in a specific order. In the
> example this would correspond to order the groups for example by the
> size of captial of each country. This ordering information needs to
> bes supplied with the style-sheet and not with the XML-document.
OK - the first thing is to have the data about the size of the capital
of each country somewhere. You could define it as a global variable
within the stylesheet, but it would be cleaner, easier to maintain and
have the advantage of working without extension functions (or XSLT
1.1) if you defined it in a separate document:
---- cities.xml ----
<cities>
<city name="Paris" country="France" population="1" />
<city name="Roma" country="Italy" population="6"/>
<city name="Nice" country="France" population="3"/>
<city name="Madrid" country="Espana" population="9"/>
<city name="Milano" country="Italia" population="5"/>
<city name="Firenze" country="Italia" population="4"/>
<city name="Napoli" country="Italia" population="7"/>
<city name="Lyon" country="France" population="2"/>
<city name="Barcelona" country="Espana" population="8"/>
</cities>
----
You can access this information with the document() function, so you
can make a variable that holds the city elements in the above with:
<xsl:variable name="populations"
select="document('cities.xml')/cities/city" />
Now, given the name and country of a city, you can find the population
of that city by querying into the $populations variable:
$populations[@name = $city-name and @country = $country-name]/@population
To do the sorting, you need xsl:sort within the xsl:for-each:
<xsl:for-each select="//city[@country=current()]">
<xsl:sort />
<city>
<xsl:value-of select="@name"/>
</city>
</xsl:for-each>
You can choose what to sort by using the select attribute on xsl:sort.
You want to sort by the population of each city, retrieved via the
$populations variable. Within the select attribute, the current node
is the node that you're sorting (i.e. a city element), so the select
attribute needs to be:
<xsl:sort select="$populations[@name = current()/@name and
@country = current()/@country]
/@population" />
As a final touch, remember that the population values are numbers, so
you need to change the data-type of the sort to 'number' rather than
'text' (the default):
<xsl:sort select="$populations[@name = current()/@name and
@country = current()/@country]
/@population"
data-type="number" />
I hope that helps,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list