Microsoft XML 2.5 SDK


 

Set Operations

[This is preliminary documentation and subject to change.]

XSL Patterns supports several set operations: $any$, $all$, and |.

$any$ and $all$ Operators

The $any$ keyword means that a condition will hold true if any item in a set meets that condition. The $all$ keyword means that a condition will hold true only if all elements in a set meet the condition. The $any$ and $all$ keywords appear before the expression.

You use $any$ and $all$ when using comparison operations. For example, the following expression means return book elements where the first author element is equal to "Bob":

book[author="Bob"]

The following expression means return book elements where any author element is "Bob":

book[$any$ author="Bob"]

The following expression means return book elements where all author elements are "Bob":

book[$all$ author = "Bob"]

When a book has only one "author" child element, these three expressions are equivalent.

The first expression provides the best performance results of the three, because it examines only the first child element. The second expression traverses children until an author child with the value "Bob" is found (or none is found), and the third traverses all children.

Operations on sets of elements can often return results that contradict your expectations. For example, it is possible to define two filter patterns that, because one uses the equality operator and the other uses the inequality operator, you would expect to return different results. However, when performing set operations, it is possible that these two filter patterns return the same result.

Consider the filter patterns "myelement[$any$ mychild = a]" and "myelement[$any$ mychild != a]", applied to the following XML data:

<myelement>
  <mychild>a</mychild>
  <mychild>b</mychild>
</myelement>

The first pattern is able to find a "myelement" element that has a "mychild" element equal to "a"; the second pattern is also able to find a "myelement" element that has a "mychild" element that is not equal to "a". Both filter patterns return the same element.

Use the $all$ keyword to indicate that every element in the set must match the supplied value.

Examples

Find all author elements where any one of the last names is Bob:

author[$any$ last-name = "Bob")]

Find all author elements where none of the last-name elements are Bob:

author[$all$ last-name != "Bob"]

"|" operator

The "|" or union operator returns the union of two queries; that is, it returns the set of nodes returned for one query combined with the set of nodes that satisfy the other query. Multiple union operators can be combined to union together the results of multiple queries. The union operator preserves document order and does not return duplicates.

The Microsoft implementation extends the union operator to be available anywhere in a query, not just at the top level. To support this behavior, the following constraint is applied to unions: All queries combined with the union operator must be from the same subtree and have the same root.

For example, you cannot use the id with the union operator, because the id method can return a node from any location in the tree. This can violate the constraint that both queries start at the same root. Similarly, you cannot use the parent operator ".." where it would cause one of the queries to start at a different root node.

The following table demonstrates examples of valid and invalid queries based on these constraints.

Valid use of | (same subtree) Invalid use of | (different subtrees)
a | b | c a | /b | c
/a | /b | /c a | /b | c
a | . a | id('C1')
a | b a | ../b
a | b a | context(-2)/b
id(x | y) id(x) | id(y)

Examples

Find all first-names and last-names:

first-name | last-name

Find all books and magazines from a bookstore:

bookstore/(book | magazine)

Find all books and all authors:

book | book/author

Find the first-names, last-names, or degrees from authors within either books or magazines:

(book | magazine)/author/(first-name | last-name | degree)

Find all books with author/first-name equal to "Bob" and all magazines with price less than 10:

book[author/first-name = "Bob"] | magazine[price $lt$ 10]

The following will return the first node that matches, not multiple nodes:

id(x | y)

Precedence

Precedence order (from highest precedence to lowest) between Boolean and comparison operators is shown in the following table.

1. ( ) Grouping
2. [ ] Filters
3. ! Method invocation
4. / // Path operations
5. $any$ $all$ Set operations
6. = != $lt$ $le$ $gt$ $ge$ $eq$ $ne$ $ieq$ Comparisons
7. | Union
8. not() Boolean not
9. and Boolean and
10. or Boolean or

See Also

Sample Data, XSL Pattern Examples