XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition (232 page)

BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition
12.84Mb size Format: txt, pdf, ePub

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

  select = 
{expression}

  


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.

Other books

Blood Harvest by James Axler
Dead and Dateless by Kimberly Raye
Devour by Andrea Heltsley
Fairytale Come Alive by Kristen Ashley
Emily's Dream by Jacqueline Pearce
Crónica de una muerte anunciada by Gabriel García Márquez