Your query results may consist of several FLWORs or other expressions that each return a result sequence. In addition, the sequences you use in your for
and let
clauses may be composed from more than one sequence.
There are four ways to combine two or more sequences to form a third sequence. They differ in which items are selected, whether their order is affected, whether duplicates are eliminated, and whether atomic values are allowed in the sequences.
The first way to merge two sequences is simply to create a third sequence that is the concatenation of the first two. This is known as a sequence constructor, and it uses parentheses and commas to concatenate two sequences together. For example:
let $prods := doc("catalog.xml")//product let $items := doc("order.xml")//item return ($prods, $items)
returns a sequence that is the concatenation of two other sequences, $prods
and $items
. The items in $prods
are first in the sequence, then the items in $items
, in the order they appear in that sequence. No attempt is made to eliminate duplicates or sort the items in any way.
Note that concatenation is the only way to combine sequences that contain atomic values; union
, intersect
, and except
work on sequences that contain nodes only.
Another approach to combining sequences of nodes is via a union expression, which is indicated by the keyword union
or the vertical bar character (|). The two operators have the exact same meaning. The resulting nodes are rearranged into document order. Path expressions such as:
doc("catalog.xml")//product/(number | name)
use the vertical bar operator to select the union of the number
children and the name
children of product
. An equivalent alternative is to use the vertical bar operator to separate two entire multistep path expressions, as in:
doc("catalog.xml")//product/number | doc("catalog.xml")//product/name
Unlike simple concatenation, using a union expression eliminates duplicate nodes. Duplicates are determined based on node identity, not typed value or string value. That means an expression like:
doc("catalog.xml")//product/@dept | doc("order.xml")//item/@dept
results in all 10 dept
attributes (four from catalog.xml
and six from order.xml
), because it does not eliminate the duplicate department values.
A union eliminates duplicate nodes not just between the sequences, but also within either of the original sequences.
An intersect
expression results in a sequence that contains only those nodes that are in both of the original sequences. As with union expressions, duplicate nodes (based on node identity) are eliminated, and the resulting nodes are rearranged into document order. For example, the expression:
let $prods := doc("catalog.xml")//product
return $prods[@dept = "ACC"] intersect
$prods[number = 443]
returns the third product element in the catalog.
An except
expression results in a sequence that contains only nodes that are in the first sequence, but not in the second. As with union expressions, duplicate values (based on node identity) are eliminated, and the resulting nodes are rearranged into document order. For example, the expression:
doc("catalog.xml")//product/(* except
number)
returns all the element children of product
except for number
elements. The parentheses are required because the slash (/) operator has precedence over the except
operator. Without the parentheses, it would be interpreted as two separate path expressions: doc("catalog.xml")//product/*
and number
. This is equally true for the other operators in this section.
3.139.83.199