4

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?

bitmask
  • 32,434
  • 14
  • 99
  • 159

3 Answers3

5

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>
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
2

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()

Community
  • 1
  • 1
Amit
  • 21,570
  • 27
  • 74
  • 94
1

In XPath 2.0, try using expressions such as $var castable as xs:integer or $var castable as xs:double.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164