xsl:sequence


The <xsl:sequence> element 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 <xsl:perform- sort > ) 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 , <xsl:sequence> is often used to return a single item.

Changes in 2.0

This instruction is new in XSLT 2.0

Format

 <xsl:sequence   select? =  expression  <!-- Content: <xsl:fallback>* --> </xsl:sequence> 

Position

<xsl:sequence> is an instruction, and may be used anywhere within a sequence constructor. It is often used within <xsl:function> , to define the value that the function returns.

Attributes

Name

Value

Meaning

select optional

Expression

Computes the value that the <xsl:sequence> instruction will return

Content

The only content permitted is <xsl:fallback> . Any contained <xsl:fallback> 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

If a select attribute is present, then the XPath expression contained in this attribute is evaluated, and the result of the XPath expression is returned as the result of the <xsl:sequence> instruction.

If no select attribute is present, then the sequence constructor is evaluated, and this provides the result of the <xsl:sequence> 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:

  <xsl:variable name="discounted-price">   <xsl:choose>   <xsl:when test="@discount">   <xsl:value-of select="@price - @discount"/>   </xsl:when>   <xsl:otherwise>   <xsl:value-of select="@price"/>   </xsl:otherwise>   </xsl:choose>   </xsl:variable>  

This works, but the problem is that the result is not a number, but a temporary tree (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 sensitive to data type, such as comparison or sorting, you might get an unexpected answer.

In XSLT 2.0, using the <xsl:sequence> instruction, you can rewrite this as:

  <xsl:variable name="discounted-price" as="xs:double">   <xsl:choose>   <xsl:when test="@discount">   <xsl:sequence select="@price - @discount"/>   </xsl:when>   <xsl:otherwise>   <xsl:sequence select="@price"/>   </xsl:otherwise>   </xsl:choose>   </xsl:variable>  

Within the <xsl:when> and <xsl:otherwise> branches, we now use <xsl:sequence> rather than <xsl:value-of> , to avoid creating a text node that we don't need. Look at the example carefully :

  • The first <xsl:sequence> 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 <xsl:variable> element ensures that whatever the numeric type of the result, it will be converted to an xs:double .

  • The second <xsl:sequence> instruction simply returns the attribute node @price itself. The as attribute on the <xsl:variable> 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 string value of the attribute is converted to xs:double by casting.

  • The «as="xs:double" » on the <xsl:variable> 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, casting to xs:double gives an error (rather than NaN) if the input is non-numeric.

  • The first <xsl:sequence> instruction could be replaced by <xsl:copy-of> without any change in the meaning. When the select attribute returns atomic values, <xsl:sequence> and <xsl:copy-of> have exactly the same effect. If the second <xsl:sequence> instruction were replaced by <xsl:copy-of> , however, the effect would be subtly different. <xsl:copy-of > would create a copy of the attribute node, which is quite unnecessary in this case.

  • Without the «as="xs:double" » on the <xsl:variable> element, all our efforts to return a numeric value rather than a temporary tree would be wasted ; when <xsl:variable> 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.

It would be possible to rewrite this whole construct as:

  <xsl:variable name="discounted-price" as="xs:double"   select="if (@discount)   then @price - @discount   else @price"/>  

This illustrates that when you are calculating values, you often have a choice as to whether to do the work at the XPath level or at the XSLT level. My own preference with simple expressions such as this is to use the XPath approach, unless there is a need to use facilities that are only available at the XSLT level, such as the ability to create new nodes, or the more powerful instructions available in XSLT such as <xsl:number>, <xsl:analyze-string> , or <xsl:for-each- group > .

By far the most common use of <xsl:sequence> is the evaluation of the result of a stylesheet function, and there are examples of this under <xsl:function> on page 300.

The <xsl:sequence> instruction also enables template rules to return atomic values, or references to existing nodes. An example of the possibilities this opens up is shown in the section Simulating Higher Order Functions on page 198, which shows a generalized function for finding cycles in any XML data source, regardless of how the relationships are represented.

See Also

  • <xsl:function> on page 300.

  • <xsl:copy-of> on page 245.

  • <xsl:template> on page 450.




XSLT 2.0 Programmer's Reference
NetBeansв„ў IDE Field Guide: Developing Desktop, Web, Enterprise, and Mobile Applications (2nd Edition)
ISBN: 764569090
EAN: 2147483647
Year: 2003
Pages: 324

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net