The comparison expression (XPath, XQuery) is used to compare two given sequences. There are three different types of comparison expressions. These are the Value Comparisons, the General Comparisons, and the Node Comparisons.
Each of these comparisons has its own specific use. There are some important differences between the comparisons. Using the wrong comparison may cause unexpected results.
Value comparisons (XPath, XQuery) are used to compare single values. The value comparison operators are
ne (not equal),
lt (lower than),
le (lower than or equal),
gt (greater than), and
ge (greater than or equal).
How it works
A value comparison consists of a few steps. First, both operands will be atomized. The result of this is called the atomized operand. If one of the atomized operands is an empty sequence, the comparison will return an empty sequence.
Value comparison resulting in an empty sequence
"abc" eq ()
The next step is to check the length of both atomized operands. Remember that the value comparison only accepts single values. If one of the operands is not a singleton sequence, the value comparison will raise a type error (XPTY0004).
Value comparison resulting in a type error XPTY0004
"abc" eq ("a", "b", "c")
Each atomized operand now for sure contains exactly one value. Atomized operands of the type xs:untypedAtomic will be cast to xs:string. If the atomized operands are instances of different primitive types, then:
Both operands are cast to xs:string if each operand is of the types xs:string or xs:anyURI;
Both operands are cast to xs:float if each operand is of the types xs:float or xs:decimal;
Both operands are cast to xs:double if each operand is of the types xs:double, xs:float, or xs:decimal;
Otherwise a type error is raised (XPTY0004)
Finally, the values are compared.
General comparisons (XPath, XQuery) are used to compare sequences that may contain multiple values. The general comparison operators are = (equal), != (not equal), < (lower than), <= (lower than or equal), > (greater than), >= (greater than or equal).
How it works
This explanation is relevant only when XPath 1.0 compatibility mode is set to false. This is the case for all uses of XPath and XQuery within Fonto.
First, both operands are atomized. This results in two sequences of atomized values. The general comparison will return true if there is a pair of atomic values that have the so-called required magnitude relationship. Otherwise the result is false or an error.
If both atomic values which are being compared are an instance of
xs:untyped, they are cast to the type
xs:string. If exactly one of both atomic values is an instance of
xs:untyped, it is cast to a type depending on the other value's dynamic type, according to the following rules:
If the other value is a numeric type or is derived from a numeric type, the value is cast to
If the other value is
xs:dayor is derived from
xs:day, the value is cast to
If the other value is
xs:yearor is derived from
xs:year, the value is cast to
In all other cases, the value is cast to the primitive type of the other value.
If a cast operation is not successful, the comparison will raise a dynamic error (FORG0001).
After performing the conversions, the atomic values are compared using one of the value comparison operators. Which value comparison operator (
ge) is used depends on which comparison operator (
>=) was used. The values have the required magnitude relationship if and only if the result of this value comparison is true.
An implementation may return as soon as it finds a pair of values with the required magnitude relationship or when it encounters an error. This means that the result of a general comparison is not deterministic in the presence of errors.
Node comparisons (XPath, XQuery) are used to compare two given nodes. The node comparison operators are
<< (precedes), and
>> (follows). Node comparisons can compare two nodes based on their identity or by their document order.
How it works
Each operand must be either a single node or an empty sequence; otherwise a type error (XPTY0004) is raised. If either operand is an empty sequence, the result of the comparison is an empty sequence.
A comparison with the
is operator is true when both operands are the same node, otherwise it is false. A comparison with the
<< operator returns true when the left operand node precedes the right operand node in document order; otherwise it returns false. A comparison with the
>> operator returns true when the left operand node follows the right operand node in document order; otherwise it returns false.
Node comparison returning true
//element1 is //*[@id = "1"]
Node comparison returning false
//element1 is //element2
Node comparison precedes
//element1 << //element2
Node comparison follows
//element2 >> //element1