使用XSL按位置排序

时间:2018-08-16 17:29:28

标签: xml xslt

我正在尝试使用xsl:sort来反转XML / XSLT中的列表,但是它似乎没有做任何事情。

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>

预期结果:

Battleaxe = PARAM4
Battleaxe = PARAM3
Battleaxe = PARAM2
Battleaxe = PARAM1

实际结果:

Battleaxe = PARAM1
Battleaxe = PARAM2
Battleaxe = PARAM3
Battleaxe = PARAM4

如果有帮助,我正在使用xsltproc,版本:

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

使用xsltproc --verbose运行时,我没有提到在输出中的任何地方进行排序

我必须在这里遗漏一些明显的东西...

编辑:

好的,即使您先前已将position()看起来始终处于升序。我想这很有道理

这与How to do an XSL:for-each in reverse order不同,因为我没有这样的id属性,只想使用一些基于位置的逻辑。是否有类似length()的函数可以用来手动将其反转?

2 个答案:

答案 0 :(得分:1)

如果您要使用数字序列4, 3, 2, 1,则可以输出/计算position()而不是last() - position() + 1。但是您不必为此排序。

答案 1 :(得分:1)

xsl:sort/@select表达式中,上下文序列是未排序的序列,因此position()为您提供项目按其原始未排序顺序的位置。因此,使用select="position()" order="descending" data-type="number"进行排序会反转输入顺序。

相反,在xsl:for-each的正文中,position()为您提供了该项目在排序序列中的位置。