Is it possible in XSLT to sort in alphabetical order, with 5 items as "preferred".
i.e. given
<teams>
<team id="142" name="Scotland" />
<team id="110" name="Liverpool" />
<team id="13" name="Manchester United" />
<team id="123" name="England" />
<team id="84" name="Chelsea" />
<team id="295" name="Wales" />
<team id="49" name="Arsenal" />
<team id="126" name="Northern Ireland" />
<team id="121" name="Republic of Ireland" />
<team id="42" name="Manchester City" />
<team id="298" name="Tottenham Hotspur" />
<team id="299" name="Bolton" />
</teams>
I require the national teams to be sorted first in a certain order, followed by the rest in alphabetical order:
<teams>
<team id="123" name="England" />
<team id="126" name="Northern Ireland" />
<team id="121" name="Republic of Ireland" />
<team id="142" name="Scotland" />
<team id="295" name="Wales" />
<team id="49" name="Arsenal" />
<team id="299" name="Bolton" />
<team id="84" name="Chelsea" />
<team id="110" name="Liverpool" />
<team id="42" name="Manchester City" />
<team id="13" name="Manchester United" />
<team id="298" name="Tottenham Hotspur" />
</teams>
I have been trying, but failing.
Is there a neat way to do this, or do you have to sort the national teams individually, followed by a sort which excludes all the national teams?
In your XSLT, are you able to make use of extension functions?
If so, one method is to modify the existing list of nodes in-line, to create a new node set but with an extra 'sortname' attribute on each node. You can then iterate through this new node set, sorting using the new 'sortname' attribute:
In the example above, I prefix a '1' onto any national team, and a '2' on any domestic team, and then sort on this new attribute.
See information on Node Sets to see what XSLT processers support which extensions.
You could do this:
The whole
<my:data>
could be moved to a secondary XML/config file, where you can also leave off the "my" namespace.After that, one line would need a small change:
The output of the above is somewhat unsurprising :-)
Have you seen xsl:sort element, you can create two or more sorting criteria by combining xsl:apply-templates and xsl:sort
Indeeed, here is a sample where some countries comes first, in a predefined order, then all the others. Note that these are elements, not attributes as above.
Sample result:
Country
Tim C has already given a nice answer, but maybe a simpler way will suffice in your case. You could simply specify two
xsl:sort
conditions: The first will sort by preferred/not-preferred items, the second one alphabetically by name:Please note that you have to invert the first condition using
not()
. The reason is that the boolean result of your expression is converted to a number (0 is false, 1 is true) and hence the items evaluating to 'false' will be listed first.