2

我在用着

<xsl:sort />

对表中的行进行排序。的价值

@result 

可以失败、忽略或通过。由于它是按字母顺序排序的,它不会按我想要的顺序出现。哪个是

失败 - 忽略 - 通过

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

这是我的代码

<xsl:apply-templates select="results/test-case">
<xsl:sort select="@result" /> 
</xsl:apply-templates>
4

3 回答 3

9

在您的问题中,您要求的顺序与字母顺序一致,因此纯文本<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$sortOrder

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

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

将完成这项工作。在concat一般情况下,它可以处理排序中的一个项目是另一个项目的子字符串的情况。例如,对于'|Passed|Pass|Failed|Fail|'concat 的排序是必需的,否则“通过”将被视为与“通过”相同,而不是在它之后始终排序。

于 2013-11-05T11:40:00.290 回答
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>

该文件可以使用 XSLT 获取document,然后用作排序索引:

<?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>

这样,排序直接使用排序索引的数字索引值,而不必从编码字符串的长度中导出它们。它看起来更干净,但正如我所说,它并不那么酷。:-)

于 2013-11-09T23:36:36.810 回答
0

XSLT 2.0 有一个更优雅的方式:

<xsl:sort select="index-of(('Passed', 'Failed', 'Ignored'), .) "/>
于 2020-03-27T18:23:43.363 回答