Comparison expressions are used to compare values. There are three kinds of comparison expressions: general, value, and node.
General comparisons
are used for comparing atomic values or nodes that contain atomic values. Table 3-2 shows some examples of general comparisons. They use the operators =
(equal to), !=
(not equal to), <
(less than), <=
(less than or equal to), >
(greater than), and >=
(greater than or equal to). Unlike in XSLT, you don't need to escape the <
operator as <
; in fact, it won't be recognized if you do.
Table 3-2. General comparisons
Example |
Value |
---|---|
|
|
|
|
|
|
|
|
|
|
|
Type error |
If either operand is the empty sequence, the expression evaluates to false
.
General comparisons can operate on sequences of more than one item, as well as empty sequences. If one or both of the operands is a sequence of more than one item, the expression evaluates to true
if the corresponding value comparison is true for any combination of two items from the two sequences. For example, the expression (2, 5) < (1, 3)
returns true
if one or more of the following conditions is true:
2 is less than 1
2 is less than 3
5 is less than 1
5 is less than 3
This example returns true
because 2 is less than 3. The expression (2, 5) > (1, 3)
also returns true
because there are values in the first sequence that are greater than values in the second sequence.
General comparisons are useful for determining if any values in a sequence meet a particular criterion. For example, if you want to determine whether any of the products are in the ACC department, you can use the expression:
doc("catalog.xml")/catalog/product/@dept = 'ACC'
This expression is true
if at least one of the four dept
attributes is equal to ACC.
When comparing two values, their types are taken into account. Values of like types (e.g., both numeric, or both derived from the same primitive type) can always be tested for equality using the =
and !=
operators. However, a few types[*] do not allow their values to be compared using the other comparison operators such as <
and >=
. The processor may raise a type error if the two operands contain any incomparable values, as shown in the last row of Table 3-2.
When comparing any two of the atomic values in each operand, if one value is typed, and the other is untyped, the untyped value is cast to the other value's type (or to xs:double
if the specific type is numeric). For example, you can compare the untyped value of a number
element with the xs:integer
500, as long as the number
element's content can be cast to xs:double
. If both operands are untyped, they are compared as strings.
Value comparisons differ fundamentally from general comparisons in that they can only operate on single atomic values. They use the operators eq
(equal to), ne
(not equal to), lt
(less than), le
(less than or equal to), gt
(greater than), and ge
(greater than or equal to). Table 3-3 shows some examples.
Table 3-3. Value comparisons
Example |
Value |
---|---|
|
|
|
|
|
Type error, if |
|
|
|
|
|
Type error |
Unlike general comparisons, if either operand is the empty sequence, the empty sequence is returned. In this respect, the empty sequence behaves like null in SQL.
Each operand of a value comparison must be either a single atomic value, a single node that contains a single atomic value, or the empty sequence. If either operand is a sequence of more than one item, a type error is raised. For example, the expression:
doc("catalog.xml")/catalog/product/@dept eq 'ACC'
raises an error, because the path expression on the left side of the operator returns more than one dept
attribute. The difference between general and value comparisons
is especially important in the predicates of path expressions.
When comparing typed values, value comparisons have similar restrictions to general comparisons. The two operands must have comparable types. For example, you cannot compare the string "4"
with the integer 3
. In this case, one value must be explicitly cast to the other's type, as in:
xs:integer(
"4")
gt 3
However, value comparisons treat untyped data differently from general comparisons. Untyped values are always treated like strings by value comparisons. This means that if you have two untyped elements that contain numbers, they will be compared as strings unless you explicitly cast them to numbers. For example, the expression:
xs:integer(
$prodNum1)
gtxs:integer(
$prodNum2)
explicitly casts the two variables to the type xs:integer
.
You also must perform an explicit cast if you are comparing the value of an untyped element to a numeric literal. For example, the expression:
doc("catalog.xml")/catalog/product[1]/number gt 1
will raise a type error if the number
element is untyped, because you are essentially comparing a string to a number. Because of these complexities, you may prefer to use general comparisons if you are using untyped data.
Another type of comparison is the node comparison. To determine whether two operands are actually the same node, you can use the is
operator. Each of the operands must be a single node, or the empty sequence. If one of the operands is the empty sequence, the result is the empty sequence.
The is
operator compares the nodes based on their identity rather than by any value they may contain. To compare the contents and attributes of two nodes, you can use the deep-equal
built-in function instead.
Table 3-4 shows some examples of node comparisons. They assume that the variables $n1
and $n2
are bound to two different nodes.
Table 3-4. Node comparisons
Example |
Value |
---|---|
|
|
|
|
|
|
|
|
In the last example of the table, even though the second and third products have the same value for their dept
attributes, they are two distinct attribute nodes.
[*] These types are xs:hexBinary
, xs:base64Binary
, xs:NOTATION
, xs:QName
, xs:duration
, and all the date component types starting with g
.
3.135.247.181