我有一种情况,我必须根据变量的内容执行排序。
在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做,我找不到替代方案。我该怎么办?
答案 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-templates
或for-each
),这是次优的。
如果您确实不想这样做,您还可以创建包含排序键的节点集。这需要node-set()
扩展功能,这在大多数实现中都是支持的(无论如何我已经使用过)。
在XPath 1.0中有一个用于执行内联条件的构造:请参阅this answer from Tomalak。我自己也没有使用它,即使是二元条件,我担心任何使用它的人都是三方面的。但这是你的电话。