How can I check if a node value is a number using XPath?
Any ideas?
Test the value against NaN:
<xsl:if test="string(number(myNode)) != 'NaN'">
<!-- myNode is a number -->
</xsl:if>
This is a shorter version (thanks @Alejandro):
<xsl:if test="number(myNode) = myNode">
<!-- myNode is a number -->
</xsl:if>
Required item type of first operand of '=' is numeric; supplied value has item type xs:string;), Dimitre's solution works fine however.The shortest possible way to test if the value contained in a variable $v can be used as a number is:
number($v) = number($v)
You only need to substitute the $v above with the expression whose value you want to test.
Explanation:
number($v) = number($v) is obviously true, if $v is a number, or a string that represents a number.
It is true also for a boolean value, because a number(true()) is 1 and number(false) is 0.
Whenever $v cannot be used as a number, then number($v) is NaN
and NaN is not equal to any other value, even to itself.
Thus, the above expression is true only for $v whose value can be used as a number, and false otherwise.
number($v) = number($v) yields a different result from number($v) = $v?number($v) = number($v) yields a different result from number($v) = $v? Doubtless that's derivable from what you wrote, but I'm not seeing where you addressed this question explicitly. Sorry if I'm being dense. IOW, does your solution and @Oded's/@Alejandro's solution always yield the same results?number($v) = $v fails me because the $v (or in my case is a tag instead of a variable) is defined as numeric on its schema. That's why when testing the expression, I got element is invalid - The value 'N/A' is invalid according to its datatype. This is where NaN is not equal to any other value, even to itself helps.I'm not trying to provide a yet another alternative solution, but a "meta view" to this problem.
Answers already provided by Oded and Dimitre Novatchev are correct but what people really might mean with phrase "value is a number" is, how would I say it, open to interpretation.
In a way it all comes to this bizarre sounding question: "how do you want to express your numeric values?"
XPath function number() processes numbers that have
Note that this doesn't include expressions for numerical values that
These are not just made up criteria. An element with content that is according to schema a valid xs:float value might contain any of the above mentioned characteristics. Yet number() would return value NaN.
So answer to your question "How i can check with XPath if a node value is number?" is either "Use already mentioned solutions using number()" or "with a single XPath 1.0 expression, you can't". Think about the possible number formats you might encounter, and if needed, write some kind of logic for validation/number parsing. Within XSLT processing, this can be done with few suitable extra templates, for example.
PS. If you only care about non-zero numbers, the shortest test is
<xsl:if test="number(myNode)">
<!-- myNode is a non-zero number -->
</xsl:if>
You could always use something like this:
string(//Sesscode) castable as xs:decimal
castable is documented by W3C here.