Comparison Expressions

Comparison expressions are used to compare values. There are three kinds of comparison expressions: general, value, and node.

General Comparisons

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 &lt;; in fact, it won't be recognized if you do.

Table 3-2. General comparisons

Example

Value

doc("catalog.xml")/catalog/product[2]/name = 'Floppy Sun Hat'

true

doc("catalog.xml")/catalog/product[4]/number < 500

false

1 > 2

false

( ) = (1, 2)

false

(2, 5) > (1, 3)

true

(1, "a") = (2, "b")

Type error

If either operand is the empty sequence, the expression evaluates to false.

General comparisons on multi-item sequences

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.

General comparisons and types

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

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

3 gt 4

false

"abc" lt "def"

true

doc("catalog.xml")/catalog/product[4]/number lt 500

Type error, if number is untyped or nonnumeric

<a>3</a> gt <z>2</z>

true

<a>03</a> gt <z>2</z>

false, since a and z are untyped and treated like strings

(1, 2) eq (1, 2)

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) gt xs: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.

Node Comparisons

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

$n1 is $n2

false

$n1 is $n1

true

doc("catalog.xml")/catalog/product[1] is

doc("catalog.xml")//product[number = 557]

true

doc("catalog.xml")/catalog/product[2]/@dept is

doc("catalog.xml")/catalog/product[3]/@dept

false

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.8.212