使用xslt sort对给定顺序进行排序

New*_*oma 2 xml xslt-1.0

我正在使用

<xsl:sort />
Run Code Online (Sandbox Code Playgroud)

排序表中的行.的价值

@result 
Run Code Online (Sandbox Code Playgroud)

可能失败,被忽略或通过.由于按字母顺序排序,它不会按我想要的顺序出现.这是

失败 - 被忽略 - 通过

我如何实现这一点我正在使用xslt 1.0

这是我的代码

<xsl:apply-templates select="results/test-case">
<xsl:sort select="@result" /> 
</xsl:apply-templates>
Run Code Online (Sandbox Code Playgroud)

Ian*_*rts 8

在您的问题中,您要求的顺序与字母顺序一致,因此平原<xsl:sort select="@result" />应该正常工作.但是在需要非字母固定排序的情况下,我倾向于使用以下技巧.

首先在变量中定义顺序,其中的条目由某些字符分隔,而不是任何选项的一部分:

<xsl:variable name="sortOrder" select="'|Passed|Failed|Ignored|'" />
Run Code Online (Sandbox Code Playgroud)

然后用

<xsl:sort data-type="number" select="string-length(
    substring-before($sortOrder, concat('|', @result, '|')))" />
Run Code Online (Sandbox Code Playgroud)

这里的技巧是,substring-before($sortOrder, concat('|', @result, '|'))@result传递时为空字符串,"|Passed"何时@result为失败"|Passed|Failed"@result为字符串,忽略时为字符串.因此,通过这些字符串的长度以数字方式排序将产生由下式给出的排序$sortOrder.

在这种特殊情况下,你甚至都不需要的concat,只是

<xsl:sort data-type="number" select="string-length(
    substring-before($sortOrder, @result))" />
Run Code Online (Sandbox Code Playgroud)

会做的.该concat是有在一般情况下处理的情况下在订货一个产品的另一个子.例如,对于'|Passed|Pass|Failed|Fail|'concat 的排序是必需的,否则"Pass"将被视为与"Passed"相同,而不是在它之后一致地排序.