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

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

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:

  • If the schema type is a simple type, the result is, in general, a sequence of zero or more atomic values. For example, if the type is
    xs:NMTOKENS
    , the result is a sequence of atomic values of type
    xs:NMTOKEN
    . If the type is a user-defined type defined as a list of
    xs:unsignedInteger
    values, then the typed value is a sequence of atomic values of type
    xs:unsignedInteger
    . If the schema type is a union type allowing a choice of
    xs:integer
    or
    xs:string
    , then the typed value will be either an
    xs:integer
    or an
    xs:string
    .
  • If the schema type is a complex type (which implies that the node is an element), there are four cases to consider:
    • The type may be a complex type with simple content. This means that the type allows attributes but does not allow child elements. In this case the element content is processed exactly as for a simple type, as described above. The attributes are ignored.
    • The type may allow mixed content (defined using
      mixed=“true”
      on the type definition in the schema). In this case the typed value is the same as the string value, which is the concatenation of all the text node descendants of the element. For example, the typed value of the element
      H2O
      is the string
      H2O
      . The result is labeled as an untyped atomic value.
    • The type may define that the element is always empty. In this case, the typed value is an empty sequence.
    • If the type allows element content only, then atomizing the element is an error. A system that does static type checking may report this as a compile-time error; otherwise, it will be reported at runtime. You can avoid this error by using the string value of the element instead of its typed value; for example, by writing
      string($emp)
      instead of
      data($emp)
      .

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

as zero or more

elements, and the content model of the

element to contain a
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())...

Other books

Unstoppable by Scott Hildreth
Seaweed Under Water by Stanley Evans
Justice by Rhiannon Paille
No Reservations by Lilly Cain
The King's Man by Pauline Gedge
Connor by Nhys Glover