Read XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition Online
Authors: Michael Kay
First, some general remarks about sequences.
Sequences (unlike nodes) do not have any concept of identity. Given two values that are both sequences, you can ask (in various ways) whether they have the same contents, but you cannot ask whether they are the same sequence.
Sequences are immutable. This is part of what it means for a language to be free of side effects. You can write expressions that take sequences as input and produce new sequences as output, but you can never modify an existing sequence in place.
Sequences cannot be nested. If you want to construct trees, build them as XML trees using nodes rather than atomic values.
A single item is a sequence of length one, so any operation that applies to sequences also applies to single items.
Sequences do not have any kind of type label that is separate from the type labels attached to the items in the sequence. As we will see in Chapter 11, you can ask whether a sequence is an instance of a particular sequence type, but the question can be answered simply by looking at the number of items in the sequence, and at the type labels attached to each item. It follows that there is no such thing as (say) an “empty sequence of integers” as distinct from an “empty sequence of strings”. If the sequence has no items in it, then it also carries no type label. This has some real practical consequences, for example, the
sum()
function, when applied to an expression that can only ever return a sequence of
xs:duration
values, will return the integer 0 (not the zero-length duration) when the sequence is empty, because there is no way at runtime of knowing that if the sequence hadn't been empty, its items would have been durations.
Functions and operators that attach position numbers to the items in a sequence always identify the first item as number 1 (one), not zero. (Although programming with a base of zero tends to be more convenient, Joe Public has not yet been educated into thinking of the first paragraph in a chapter as paragraph zero, and the numbering convention was chosen with this in mind.)
This chapter covers the language constructs that handle general sequences, but there are also a number of useful functions available for manipulating sequences, and these are described in Chapter 13. Relevant functions include:
count()
,
deep-equal()
,
distinct-values()
,
empty()
,
exists()
,
index-of()
,
insert-before()
,
remove()
,
subsequence()
, and
unordered()
.
The Comma Operator
The comma operator can be used to construct a sequence by concatenating items or sequences. We already saw the syntax in Chapter 7, because it appears right at the top level of the XPath grammar:
Expression | Syntax |
Expr | ExprSingle ( , ExprSingle)* |
ExprSingle | ForExpr | QuantifiedExpr | IfExpr | OrExpr |
Although the production rule
ExprSingle
lists four specific kinds of expression that can appear as an operand of the
,
operator, these actually cover any XPath expression whatsoever, provided it does not contain a top-level
,
.
Because the
,
symbol also has other uses in XPath (for example, it is used to separate the arguments in a function call, and also to separate clauses in
for
,
some
, and
every
expressions, which we will meet later in this chapter), there are many places in the grammar where use of a general
Expr
is restricted, and only an
ExprSingle
is allowed. In fact, the only places where a general
Expr
(one that contains a top-level comma) is allowed are: