This style sheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="pValue" select="5"/>
<xsl:template match="/">
<xsl:for-each select="list/num">
<xsl:sort select="(. - $pValue) * not(0 > . - $pValue )
- (. - $pValue) * (0 > . - $pValue)"/>
<xsl:if test="position() = 1">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
With this input:
<list>
<num>4</num>
<num>9</num>
</list>
Conclusion:
4
And this input:
<list>
<num>1</num>
<num>7</num>
</list>
Conclusion:
7
EDIT : XSLT 2.0 Solution:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="pValue" select="5"/>
<xsl:template match="/">
<xsl:variable name="vSequence"
select="/list/num/abs(. - $pValue)"/>
<xsl:variable name="vMinimum"
select="min($vSequence)"/>
<xsl:variable name="vPosition"
select="index-of($vSequence,$vMinimum)[1]"/>
<xsl:value-of select="/list/num[$vPosition]"/>
</xsl:template>
</xsl:stylesheet>
This shows that it can be an XPath 2.0 single-line expression:
/list/num[
index-of(
/list/num/abs(. - $pValue),
min(/list/num/abs(. - $pValue))
)[1]
]
user357812
source
share