Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xpath:number returns false for "0"

I have an xsl:variable that can be either the empty string or a number. So I evaluate it like this:

<xsl:if test="number($var)"><node att="{number($var)}" /></xsl:if>

This works if var is the empty string, but it has the same effect if var is 0:

From -2 to 2:

<node att="-2" />
<node att="-1" />
<node att="1" />
<node att="2" />

Is this a bug? Is there a different version of the number function that also captures 0? Do I really have to add or $var = '0' to my test statement?

like image 975
bitmask Avatar asked Feb 21 '23 16:02

bitmask


2 Answers

This is perfectly according to the XPath specification:

By definition boolean(0) is false()

You want:

<xsl:if test="number($var) = number($var)">
  <node att="{number($var)}" />
</xsl:if>

Explanation:

number($x) = number($x)

is true() exactly when $x is castable to a number.

If $x isn't castable to a number, both sides of the above comaparison evaluate to NaN, and by definition NaN isn't equal to any value, including NaN.

Note:

In case you want to check if $var is integer, then use:

<xsl:if test="floor($var) = $var">
  <node att="{$var}" />
</xsl:if>

or, alternatively:

<xsl:if test="not(translate($var, '0123456789', ''))">
  <node att="{$var}" />
</xsl:if>
like image 172
Dimitre Novatchev Avatar answered Mar 01 '23 22:03

Dimitre Novatchev


It is taken from XPath test if node value is number
Test the value against NaN:

<xsl:if test="string(number(myNode)) != 'NaN'">
    <!-- myNode is a number -->
</xsl:if>

This is a shorter version:

<xsl:if test="number(myNode) = myNode">
    <!-- myNode is a number -->
</xsl:if>


<xsl:if test="number(0)">

the expression number(0) is evaluated to the boolean false() -- because by definition

boolean(0) is false()

like image 27
jams Avatar answered Mar 01 '23 23:03

jams