Read XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition Online
Authors: Michael Kay
Some systems might deliberately choose to exploit these rules by evaluating the error cases last (or pretending to do so) so as to minimize the chance of the expression failing, but you can't rely on this.
What does this mean in practice? Suppose you have an attribute defined in the schema as follows:
Or to put it more simply, the attribute's typed value is a list of atomic values, each of which is either a decimal number or the string value
n/a
. For example, the attribute might be written
readings = “12.2 -8.4 5.6 n/a 13.1”
.
Now suppose you want to test whether the set of readings includes a negative value. You could write:
if (some $a in data(@readings) satisfies $a lt 0) then …
The chances are you will get away with this. Most processors will probably evaluate the condition
$a lt 0
against each value in turn, find that the condition is true for the second item in the list, and return
true
. However, a processor that decided to evaluate the items in reverse order would encounter the value
n/a
, compare this with zero, and hit a type error: you can't compare a string with a number. So one processor will give you the answer
true
, while another gives you an error.
You can protect yourself against this error by writing the expression as:
if (some $a in data(@readings)[. instance of xs:decimal]
satisfies $a lt 0)
then …
Or in this case, you can mask the error by writing:
if (some $a in data(@readings) satisfies number($a) lt 0) then …
This works because
number(‘n/a’)
returns
NaN
(not-a-number), and
NaN lt 0
returns
false
.