I have following question relating to XPATH1 and XPATH2:
<document>
    <val>3</val>
    <val>11</val>
    <val>3</val>
    <val>2</val>
    <val>12</val>
    <val>5</val>
    <val>0</val>
    <val>7</val>
</document>
xpath1: max
//val[not(. < //val)]
min:
//val[not(. > //val)]
xpath2:
document/val[. = max(//val)]
document/val[. = min(//val)]
Why don't I get the same result in XPATH2 processing with the xpath1-max query:
//val[not(. < //val)]
It seems that I get the LAST node (with val 7), but not the highest value ... the other way around for MIN value works fine with XPATH2 processing:
//val[not(. > //val)]
Can someone help me out there ?
Very good point.
In xpath 1 (and xslt 1.0), //val[not(. < //val)] is inherently casting the text values to numbers, and doing the comparison on numbers.
Hence, you get the correct min and max values.
However, in xpath 2 (and xslt 2.0), the text isn't cast to numeric, and instead, a string comparison is done. So using string comparison, '7' is > '12' and hence 7 will still be the highest value (it isn't returning just the last value in the list - try swapping the order of values around)
So what you should do to be safe in both xslt 1 and 2 is to use the number() function to do the cast on the text, to ensure that a numeric comparison is done.
Max:
//val[not(number(.) < //val)]
Min:
//val[not(number(.) > //val)]
Using Saxon with the stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <x>
            <Max1>
                <xsl:value-of select="//val[not(number(.) < //val)]" />
            </Max1>
            <Min1>
                <xsl:value-of select="//val[not(number(.) > //val)]" />
            </Min1>
            <Max2>
                <xsl:value-of select="/document/val[. = max(//val/text())]" />
            </Max2>
            <Min2>
                <xsl:value-of select="/document/val[. = min(//val/text())]" />
            </Min2>
        </x>
    </xsl:template>
</xsl:stylesheet>
Returns
<x>
   <Max1>12</Max1>
   <Min1>0</Min1>
   <Max2>12</Max2>
   <Min2>0</Min2>
</x>
as expected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With