Учитывая последовательность узлов S, чтобы найти узел, который имеет наибольшее значение для некоторой величины Q, «грубый» способ сделать это -
<xsl:variable name="max" selecy="max(S / Q)"/>
<xsl:for-each select="S[Q = $max]">...</xsl:for-each>
Это не очень элегантно, поскольку включает обработку Sдважды.Saxon имеет функцию более высокого порядка saxon: самый высокий (), которая делает это за один шаг, но включает в себя расширения (и функции более высокого порядка), поэтому она работает только в коммерческих версиях продукта.
Другой способ сделать это за один проход - с помощью рекурсии.
<xsl:function name="f:highest">
<xsl:param name="input" as="node()*"/>
<xsl:param name="max-so-far"/>
<xsl:param name="top-nodes"/>
<xsl:choose>
<xsl:when test="empty($input)">
<xsl:sequence select="$top-nodes"/>
</xsl:when>
<xsl:when test="Q($input[1]) = $max-so-far">
<xsl:sequence select="f:highest(remove($input, 1), $max-so-far, ($top-nodes, $input[1])"/>
</xsl:when>
<xsl:when test="Q($input[1]) > $max-so-far">
<xsl:sequence select="f:highest(remove($input, 1), Q($input[1]), $input[1]"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="f:highest(remove($input, 1), $max-so-far, $top-nodes"/>
</xsl:otherwise>
</xsl:function>
Здесь Q (узел) представляет любое выражение, которое вы оцениваете на узле, чтобы получить интересующее значение, например, number($node/@ABSPriority)
.
В XSLT 3.0 вы можете заменить рекурсивную функцию эквивалентным циклом xsl: iterate.