这种转变:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/*">
<xsl:apply-templates select="recording">
<xsl:sort select="count(week/rank[. = 1])"
data-type="number" order="descending"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="recording">
<xsl:value-of select=
"concat(title, ' / ', count(week/rank[. = 1]), '
')"/>
</xsl:template>
</xsl:stylesheet>
当应用于以下 XML 文档时(问题中没有提供!!!):
<popular-recordings-dataset>
<recording>
<title>Song1</title>
<week no="23">
<rank>1</rank>
</week>
<week no="24">
<rank>2</rank>
</week>
</recording>
<recording>
<title>Song2</title>
<week no="22">
<rank>1</rank>
</week>
<week no="24">
<rank>1</rank>
</week>
<week no="25">
<rank>1</rank>
</week>
</recording>
<recording>
<title>Song3</title>
<week no="21">
<rank>1</rank>
</week>
<week no="26">
<rank>1</rank>
</week>
</recording>
</popular-recordings-dataset>
产生想要的正确结果:
Song2 / 3
Song3 / 2
Song1 / 1
说明:您的代码的问题在于使用此表达式:
count(//rank[. = '1'])
to 的参数count()
是一个绝对XPath 表达式(以 开头/
),因此它选择rank
文档中值等于 的所有元素1
。这意味着此表达式不依赖于当前元素并且不随当前rank
元素而变化,并且对于所有rank
元素都保持相同。对常数进行排序不会改变节点集的初始顺序——正如您所见证的那样。
解决方案:
改变:
count(//rank[. = '1'])
至:
count(.//rank[. = '1'])
但更好的是,如果事先知道 XML 文档的结构,那么尽量避免使用//
伪运算符,这可能非常低效。