Read XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition Online
Authors: Michael Kay
If the node is annotated with some other type annotation, which generally will happen only as a result of schema validation, the typed value reflects the type definition in the schema:
Examples
Suppose that the variable
$x
is bound to the following element, which has been validated using a schema that defines the content model of
number
attribute of type
xs:integer
and a
colors
attribute whose type is
xs:NMTOKENS
.
Expression | Result |
data($x/row/@number) | (1, 2) |
data($x/row/@colors) | (“red”, “green”, “yellow”, “purple”) |
data($x) | Error. An element with element-only content does not have a typed value. |
data($x/row) | () |
Note that the above examples could equally well be written in the style
$x/row/@number/data(.)
.
Usage
Atomization is normally carried out automatically when an operation that expects atomic values is applied to a sequence. For example, if the argument to the
sum()
function is a set of nodes, then the typed values of those nodes will be extracted and totaled.
The
data()
function is provided so that atomization can be done explicitly in situations where it is not automatic. For example, the
count()
function does not automatically atomize its argument: it counts the nodes in the sequence, not the atomic values that result from atomization. The result is not the same, because if an element or attribute is declared in the schema to have a type such as list-of-integers, then atomizing the element or attribute may produce zero, one, or more atomic values.
Similarly, when testing the value of an element or attribute whose type is
xs:boolean
, be careful to make sure that the value is atomized: write
if (data(@married))...
rather than
if(@married)...
. This is because the value of
@married
is a sequence of zero or one attribute nodes, and the effective boolean value of a sequence of nodes (which is what the
if
expression tests) is true if there is at least one node in the sequence, regardless of its contents. If the attribute exists and has the value
married=“false”
, the test
if(@married)...
will return true. Another way of forcing atomization is to write this as
if (@married=true())...