I have an XML that contains a series of topic nodes that have a version attribute. Versioning is numeric. The topics are linked: we have topic nodes with the same ID, and different versions.
I want to select one of these topic nodes: the topic whose version is closest to, and equal or lower than, my input variable.
XML:
<topics>
<topic id="1" version="6"/>
<topic id="1" version="3"/>
<topic id="1" version="1"/>
</topics>
If my input variable is 7, I want to select the topic with version="6". If my input variable is 6, I want to select the topic with version="6". If my input variable is 5, I want to select the topic with version="3".
Something like this would work:
<xsl:variable name="ver" select="7"/>
<xsl:choose>
<xsl:when test="//topic[@version = $ver]">
<xsl:copy-of select="//topic[@version = $ver]">
</xsl:when>
<xsl:when test="//topic[@version = $ver -1]">
<xsl:copy-of select="//topic[@version = $ver -1]">
</xsl:when>
...
</xsl:choose>
But I have 16 values for 'version' and there will be more in the future. Is there a way to replace this choose/when with something that does not have to enumerate every possible value?
(using Saxon, can use XSLT 2 and 3)
In XSLT 2 and later you can use <xsl:variable name="max" select="max(//topic/@version[. < $ver])"/>
and then select //topic[@version = $max]
.
In XSLT 4 there is/will be a function highest https://qt4cg.org/specifications/xpath-functions-40/Overview.html#func-highest so that you could select e.g. highest(//topic[@version < $ver], (), function($t) { $t/@version })
in XPath or highest(//topic[@version < $ver], (), function($t) { $t/@version })
in XSLT.