如果Else If Else排序XSLT 1.0

时间:2013-10-31 17:42:48

标签: xslt xpath

我有一种情况,我必须根据变量的内容执行排序。

在XSLT 2.0中我做:

<xsl:sort select=" 
        if ($column = 'name') then name
        else if ($column = 'score') then count(//scores/score[@id=current()/@id])
        else if ($column = 'rating) then count(//ratings/rating[@id=current()/@id])
        else name"
        order={$sort}" />

但我需要为版本1.0做,我找不到替代方案。我该怎么办?

3 个答案:

答案 0 :(得分:3)

您可以定义多个排序键并安排其中一些排序键无效(通过为所有节点提供该排序键的相同值)

<xsl:sort select="name[$column = 'name']"/>
<xsl:sort select="count(/self::node()
          [$column = 'score']/scores/score[@id=current()/@id])"/>
<xsl:sort select="count(/self::node()
          [$column = 'rating']/ratings/rating[@id=current()/@id])"/>
<xsl:sort select="name"/> 

答案 1 :(得分:1)

这绝对是丑陋的,但可能是更紧凑的方法之一:

  <xsl:key name="score" match="scores/score" use="@id" />
  <xsl:key name="rating" match="ratings/rating" use="@id" />

  <!-- ... -->

  <xsl:variable name="useName" 
                select="$column != 'score' and $column != 'rating'" />
  <xsl:apply-templates select="something">
    <xsl:sort order="{$sort}" 
              data-type="{substring('numbertext', 1 + 6 * $useName, 6)}"
              select="concat(
                         substring(count(key('score', @id])), 1, 
                                   100 * ($column = 'score')),
                         substring(count(key('rating', @id])), 1, 
                                   100 * ($column = 'rating')),
                         substring(name, 1, 100 * $useName)
                      )"
              />
  </xsl:apply-templates>

答案 2 :(得分:0)

当我在XSLT 1.0中遇到这种情况时,我使用xsl:choose。当然,这意味着你必须重复你正在排序的东西(apply-templatesfor-each),这是次优的。

如果您确实不想这样做,您还可以创建包含排序键的节点集。这需要node-set()扩展功能,这在大多数实现中都是支持的(无论如何我已经使用过)。

在XPath 1.0中有一个用于执行内联条件的构造:请参阅this answer from Tomalak。我自己也没有使用它,即使是二元条件,我担心任何使用它的人都是三方面的。但这是你的电话。