如何对xsl进行升序排序,最后使用null

Chr*_*s R 4 xml xslt

我想按升序对这些元素进行排序,但最后一个而不是第一个为空,这似乎是xslt在默认情况下所做的。我已经做到了,但是想知道是否有更好的方法。这是我的例子。

<b>
    <c>2</c>
    <c>1</c>
    <c>3</c>
    <c></c>
    <c>15</c>
    <c>11</c>
    <c></c>
    <c>43</c>
    <c>4</c>
</b>


<xsl:template match="/">
    <xsl:for-each select="b/c">
        <xsl:sort select="node() = false()"/>
        <xsl:sort select="." data-type="number"/>
        Row<xsl:value-of select="position()"/>:<xsl:value-of select="."/>
    </xsl:for-each>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

给出所需的输出:

Row1:1
Row2:2
Row3:3
Row4:4
Row5:11
Row6:15
Row7:43
Row8:
Row9:  
Run Code Online (Sandbox Code Playgroud)

我当前正在<xsl:sort select="node() = false()"/>测试它是否为null,然后使用排序方式对null元素进行最后排序(null将为1,而非null将为0,因此可以正确地对它们进行排序)。

有人能提出比这更好的建议吗?

Tom*_*lak 5

<xsl:template match="/">
  <xsl:for-each select="b/c">
    <xsl:sort select="concat(
      substring('1', 1, boolean(text())),
      substring('0', 1, not(boolean(text())))
    )" />
    <xsl:sort select="." data-type="number"/>
    <xsl:text>Row</xsl:text>
    <xsl:value-of select="position()"/>
    <xsl:text>:</xsl:text>
    <xsl:value-of select="."/>
    <xsl:text>&#10;</xsl:text>
  </xsl:for-each>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

这个:

concat(
  substring('1', 1, boolean(text()) ),
  substring('0', 1, not(boolean(text())))
)
Run Code Online (Sandbox Code Playgroud)

或者产生“0”或“1”,根据是否有一个孩子文本节点,还是不行。它是两个互斥字符串的串联-XPath 1.0中穷人的if / then / else。

boolean(text())产生truefalse,然后将其转换为数字为substring()。布尔值分别转换为1或0。

上面的更完整的版本是这样的:

concat(
  substring(
    $if_str, 
    1, 
    boolean($condition) * string-length($if_str)
  ),
  substring(
    $else_str, 
    1, 
    not(boolean($condition)) * string-length($else_str)
  )
)
Run Code Online (Sandbox Code Playgroud)

  • 这是将布尔值转换为1或0,以便您可以对该值进行排序。但是您*已经可以*对布尔值进行排序;它们从假到真排序。如果只对not(boolean(text()))进行排序,则将首先获取非空元素,然后再获取空元素。 (2认同)