For another version of this example, which uses the
element-available()
function to test whether the
instruction is implemented and takes fallback action if not, see the entry for
element-available()
on page 764 in Chapter 13.
See Also
on page 420
xsl:sequence
The
instruction is used to deliver an arbitrary sequence, which may contain atomic values, nodes, or a combination of the two. It is the only XSLT instruction (with the exception of
) that can return references to existing nodes, as distinct from newly constructed nodes. Its most common use is to return the result of a stylesheet function.
Despite its name,
is often used to return a single item.
Changes in 2.0
This instruction is new in XSLT 2.0.
Format
Position
is an instruction, and may be used anywhere within a sequence constructor. It is often used within
, to define the value that the function returns.
Attributes
Name
| Value
| Meaning
|
select mandatory
| XPath Expression
| Computes the value that the
instruction will return.
|
Content
The only content permitted is
. Any contained
instructions will be ignored by an XSLT 2.0 processor but can be used to define fallback action for an XSLT 1.0 processor.
Effect
The XPath expression contained in the
select
attribute is evaluated, and its result is returned unchanged as the result of the
instruction.
Usage and Examples
This innocent-looking instruction introduced in XSLT 2.0 has far-reaching effects on the capability of the XSLT language, because it means that XSLT instructions and sequence constructors (and hence functions and templates) become capable of returning any value allowed by the XPath data model. Without it, XSLT instructions could only be used to create new nodes in a result tree, but with it, they can also return atomic values and references to existing nodes.
To take an example, suppose you want to set a variable whose value is the numeric value of the
price
attribute of the context node, minus the value of the
discount
attribute if present. In XSLT 1.0 you might have written:
This works, but the problem is that the result is not a number, but a document node (in XSLT 1.0 terminology, a result tree fragment) containing a text node that holds a string representation of the number. Not only is this an inefficient way of representing a number, it has also lost the type information, which means that if you use the value in operations that are type-sensitive, such as comparison or sorting, you might get an unexpected answer.
In XSLT 2.0, using the
instruction, you can rewrite this as:
Within the
and
branches, we now use
rather than
, to avoid creating a text node that we don't need. Look at the example carefully:
- The first
instruction contains an XPath arithmetic expression. If the source document has a schema, this assumes that the type of
@price
and
@discount
is numeric (typically,
xs:decimal
), and the result of the subtraction will be the same numeric type. If there is no schema, the nodes will be untyped, and the fact that they are used in an arithmetic expression will force the content of the attribute to be converted to an
xs:double
, which means that the result of the subtraction will also be an
xs:double
. The
as
attribute on the
element ensures that whatever the numeric type of the result, it will be converted to an
xs:double
.
- The second
instruction simply returns the attribute node
@price
itself. The
as
attribute on the
element causes the attribute node to be atomized, which extracts its typed value. If there is a schema, the node must be annotated with a numeric type for the conversion to
xs:double
to succeed. If there is no schema, then the untyped value of the attribute is converted to
xs:double
by casting.
- The
as=“xs:double”
on the
element ensures that a type error will be reported (typically at runtime) if there is no
@price
attribute, or if the content of the
@price
or
@discount
attribute is not numeric. Unlike the
number()
function, conversion to
xs:double
gives an error (rather than NaN) if the input is non-numeric.
- The first
instruction could be replaced by
without any change in the meaning. When the
select
attribute returns atomic values,
and
have exactly the same effect. If the second
instruction were replaced by
, however, the effect would be subtly different.
would create a copy of the attribute node, which is quite unnecessary in this case.
- Without the
as=“xs:double”
on the
element, all our efforts to return a numeric value rather than a temporary tree would be wasted; when
has no
select
or
as
attribute, it automatically builds a temporary tree whose content is derived from the value returned by its contained sequence constructor.