Reputation: 1289
I'm trying to use xsl:sort to invert a list in XML/XSLT, but it doesn't appear to be doing anything.
example.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:for-each select="CONTAINER/PARAM">
<xsl:sort data-type="number" order="descending" select="position()"/>
Battleaxe = <xsl:value-of select="name()" /><xsl:number value="position()" format="1" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
example.xml
<CONTAINER>
<PARAM>foo</PARAM>
<PARAM>bar</PARAM>
<PARAM>baz</PARAM>
<PARAM>quix</PARAM>
</CONTAINER>
Expected result:
Battleaxe = PARAM4
Battleaxe = PARAM3
Battleaxe = PARAM2
Battleaxe = PARAM1
Actual result:
Battleaxe = PARAM1
Battleaxe = PARAM2
Battleaxe = PARAM3
Battleaxe = PARAM4
If it helps, I'm using xsltproc, version:
Using libxml 20903, libxslt 10117 and libexslt 813
xsltproc was compiled against libxml 20626, libxslt 10117 and libexslt 813
libxslt 10117 was compiled against libxml 20626
libexslt 813 was compiled against libxml 20626
When running with xsltproc --verbose, I see no mention of sorting anywhere in the output
I've got to be missing something obvious here...
EDIT:
OK, looks like position() is always in ascending order, even if you previously reversed it. I guess that makes sense
This differs to How to do an XSL:for-each in reverse order in that I have no such id
attribute and just want to use some positional based logic. Is there something like a length()
function I can use to reverse it manually?
Upvotes: 0
Views: 1037
Reputation: 163458
In the xsl:sort/@select
expression, the context sequence is the unsorted sequence, so position()
gives you the position of an item in its original unsorted order. Hence sorting with select="position()" order="descending" data-type="number"
reverses the input order.
Within the body of the xsl:for-each
, by contrast, position()
gives you the position of the item in the sorted sequence.
Upvotes: 1
Reputation: 167696
If you want to have the sequence of numbers 4, 3, 2, 1
then instead of position()
output/compute last() - position() + 1
. But you don't have to sort for doing that.
Upvotes: 1