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

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

The rules take as input a
supplied value
and a
required type
, and they produce as output a
result value
. The required type has two parts: the
required item type
(for example, integer or element) and the
required cardinality
. The required cardinality may be
exactly-one
(when there is no occurrence indicator in the
SequenceType
as written) or
zero-or-one
,
zero-or-more
, or
one-or-more
, corresponding to the occurrence indicators
?
,
*
, and
+
.

Instead of returning a result value, the rules may also result in a type error, if the supplied value cannot be converted to the required type.

The rules are as follows:

1.
If the supplied value is an instance of the required type, return it unchanged as the result value. This includes the case where the supplied value belongs to a subtype of the required type.

2.
If the required item type is an atomic type, the supplied value is atomized. Atomization causes each node in the supplied sequence to be replaced by its typed value, while leaving any atomic values in the sequence unchanged. Note that the typed value of a node can be a sequence of zero or more atomic values. Elements declared in the schema to have element-only content have no typed value, so this operation can result in an error.

3.
Any item in the atomized sequence that is of type
xs:untypedAtomic
is cast to the required item type. Such items are most likely to arise as the result of atomizing a node in a schema-less document. This means, for example, that an attribute such as
@date-of-birth
will be acceptable where the required type is
xs:date
, provided that either (a) the attribute is annotated as an
xs:date
as a result of schema validation, or (b) the attribute is unvalidated and its textual form is acceptable as an
xs:date
.

4.
If the required item type is a numeric type (one of
xs:double
,
xs:float
,
xs:decimal
, or
xs:integer
, or a type derived from these by restricting the range of values), then any numeric value in the atomized sequence is promoted to the required numeric type where possible. An integer can be promoted to any other numeric type, a decimal can be promoted to
xs:float
or
xs:double
, and an
xs:float
can be converted to an
xs:double
. However, other conversions are not possible; for example if the required item type is
xs:integer
but the supplied value is
xs:double
, a type error will be reported.

5.
If the required item type is
xs:string
and the supplied value is of type
xs:anyURI
, then the URI is converted to a string (XDM effectively treats
xs:anyURI
as a subtype of
xs:string
, even though XML Schema does not define it that way).

If, after these conversions, the sequence conforms to the required type, then it is returned as the result value. If not, the system reports a type error. Type errors may be reported at runtime, but if the system can tell in advance that the expression will return a value of the wrong type, then they can also be reported at compile time.

These rules are not as liberal as the rules that were used in XPath 1.0 for type conversions, where, for example, a boolean could be supplied when a string was expected, and it would be treated as the string
“true”
or
“false”
. Because the type system in XSLT 2.0 is so much richer, you have to get used to the idea of thinking about what type of value you are handling, and of doing any necessary conversions yourself, using explicit casts or calls on constructor functions.

Usage

Variables are useful, as in any programming language, to avoid calculating the same result more than once.

Global variables are useful for defining constants, such as a color value, that will be used in many places throughout the stylesheet. They can also be used to extract values from the principal source document.

Unlike variables in many programming languages,
XSLT variables cannot be updated
. Once they are given an initial value, they retain this value until they go out of scope. This feature has a profound effect on the programming style used when a stylesheet needs to do calculations. The subject of
programming without assignment statements
is discussed in detail in Chapter 17.

Examples

Most XSLT variables fall into one of the three categories:

  • Variables used to avoid repeating a common expression in more than one place. This might be simply to make the code more readable or to ensure that you only have to make a change in one place if the value changes or perhaps because it gives a performance benefit.
  • Variables used to capture context-sensitive information, allowing the variable to be used after the context has changed.
  • Variables holding intermediate results, allowing a transformation to be carried out as a series of separate steps.

In each case the variable might be local or global. I'll show some examples of each kind.

Convenience Variables

Consider this example, which calculates the number of goals scored by, and against, a soccer team.

              select=“sum($matches/team[.=$this]/@score)”/>

              select=“sum($matches[team=$this]/team/@score) - $for”/>




This uses two rather complex expressions to construct the variables
for
and
against
, which calculate the number of goals scored by, and against, the team identified by the variable
$team
. It would be quite possible in this case to avoid using the variable
against
. The expression that calculates its value could equally be written at the point where the variable is used, in the second

instruction. The same is true of the
for
variable, though this time the expression would need to be written twice, in both places where the variable is used, and this might give a performance penalty. However, these variables are really being used only for clarity; it would be quite possible to write the stylesheet without them.

Other books

The Innocent Mage by Miller, Karen
Night Swimming by Robin Schwarz
The Cowboy's Temptation by Lennox, Elizabeth
New Markets - 02 by Kevin Rau
Sandlands by Rosy Thornton
Bones in the Barrow by Josephine Bell
Love Amid the Ashes by Mesu Andrews
Dangerous Undertaking by Mark de Castrique