我正在使用
<xsl:sort />
对表中的行进行排序。
的价值@result
可能失败,被忽略或通过。由于按字母顺序排序,它不会按我想要的顺序出现。这是
失败 - 被忽略了 - 通过
我如何实现这一点我正在使用xslt 1.0
这是我的代码
<xsl:apply-templates select="results/test-case">
<xsl:sort select="@result" />
</xsl:apply-templates>
答案 0 :(得分:7)
在您的问题中,您要求的顺序与字母顺序一致,因此普通<xsl:sort select="@result" />
应该正常工作。但是在需要非字母固定排序的情况下,我倾向于使用以下技巧。
首先在变量中定义顺序,其中的条目由不属于任何选项的某个字符分隔:
<xsl:variable name="sortOrder" select="'|Passed|Failed|Ignored|'" />
然后使用
<xsl:sort data-type="number" select="string-length(
substring-before($sortOrder, concat('|', @result, '|')))" />
这里的诀窍是substring-before($sortOrder, concat('|', @result, '|'))
在传递@result
时为空字符串,在"|Passed"
失败时为@result
字符串,字符串为"|Passed|Failed"
当@result
被忽略时。因此,通过这些字符串的 length 进行数字排序将产生$sortOrder
给出的排序。
在这种特殊情况下,您甚至不需要concat
,只需
<xsl:sort data-type="number" select="string-length(
substring-before($sortOrder, @result))" />
将完成这项工作。在一般情况下,concat
用于处理排序中的一个项是另一个项的子串的情况。例如,对于'|Passed|Pass|Failed|Fail|'
的排序,需要使用concat,否则“Pass”将被视为与“Passed”相同,而不是在其后一致排序。
答案 1 :(得分:2)
下面的备用XSLT肯定不像@ IanRoberts那样酷,但它在某些设置中可能会有所帮助,例如:排序顺序由另一个进程定义,因此可以在另一个XML文件中使用。
以下文件sort.xml
是定义排序顺序的简单示例:
<?xml version="1.0" encoding="ISO-8859-1"?>
<sort_indices>
<sort_index name="my_sort">
<entry key="Failed" index="2"/>
<entry key="Ignored" index="0"/>
<entry key="Passed" index="1"/>
</sort_index>
</sort_indices>
可以使用document
将此文件提取到XSLT中,然后将其用作排序索引:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:variable name="sort_index" select="document('sort.xml')/sort_indices/sort_index[@name='my_sort']"/>
<xsl:template match="/">
<test-cases>
<xsl:apply-templates select="results/test-case">
<xsl:sort select="$sort_index/entry[@key = current()/@result]/@index"/>
</xsl:apply-templates>
</test-cases>
</xsl:template>
</xsl:stylesheet>
这样排序直接使用排序索引的数字索引值,而不必从编码字符串的长度派生它们。它看起来更干净,但正如我所说,它并不那么酷。 : - )
答案 2 :(得分:0)
XSLT 2.0具有更优雅的方式:
<xsl:sort select="index-of(('Passed', 'Failed', 'Ignored'), .) "/>