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

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

The next chapter deals with operations involving types: operations that convert a value of one type into a value of another type, and operations that test the type of a value.

Chapter 11

XPath: Type Expressions

This chapter is concerned with XPath expressions that involve types. This includes operations to convert a value of one type to a value of another type (which is called casting), and operations to test whether a value belongs to a particular type.

The type system for XPath was fully explained in Chapter 5. Recall in particular that there are two separate but related sets of types we are concerned with:

  • Every value in XPath (that is, the result of every expression) is an instance of a
    sequence type
    . This reflects the fact that every XPath value is a sequence. A sequence type in general defines an
    item type
    that each of the items in the sequence must conform to, and a
    cardinality
    that constrains the number of items in the sequence. The items may be either nodes or atomic values, so item types divide into those that permit nodes and those that permit atomic values. There are also two special item types, the type
    item()
    , which permits anything, and the type
    empty-sequence()
    , which permits nothing.
  • Every element and attribute node conforms to a type definition contained in a schema, or a built-in type definition that is implicit in every schema. To distinguish these clearly from sequence types, I will refer to these types as
    schema types
    . A schema type may be either a simple type or (for elements only) a complex type. A simple type may be either a list type, a union type, or an atomic type. A type definition constrains the contents of a node (that is, the value of an attribute, or the attributes and children of an element); it does not constrain the name of the node.

We need to use careful language to avoid confusing these two views of the type system. When we have an XPath value that is a node, we will speak of the node being an
instance of
a sequence type—for example, every element is an instance of the sequence type
element()
. At the same time, the node is
annotated with
a schema type—for example, an element node may be annotated as an
mf:invoice
(which will be the name of a complex type defined in some schema).

These two sets of types (sequence types and schema types) overlap: in particular, atomic types such as
xs:integer
belong to both sets. However, list types, union types, and complex types are never used as item types or sequence types; they are used only to annotate nodes. Equally, item types such as
comment()
are only used in sequence types; they are never used to annotate nodes. This idea is illustrated in
Figure 11-1
.

The first part of this chapter is concerned with conversion of values from one type to another. These types are always atomic types; no conversions are defined for any types other than atomic types. The process of atomization, which extracts the typed value of a node, could be regarded as a conversion, but we won't treat it as such for our present purposes.

Atomic types can be referred to by the name given to them in the schema. A schema can define anonymous atomic types, but because these have no name, they can't be referenced in an XPath expression. Named atomic types are always defined by a top-level

element in a schema (more specifically, by an

element that is a child of either an

element or an

element), and these elements always have a
name
attribute.

The final part of this chapter deals with two operators (
instance
of
and
treat
as
) that take as their “operands” an arbitrary XPath value (that is, a sequence), and a sequence type. (I've written “operands” in quotes, because a true operand is always a value, and in the XPath view of the world, types are not values). These two constructs require a special syntax for describing sequence types. For example,
attribute(*,
xs:date)?
describes a sequence type whose item type matches any attribute node annotated as an
xs:date
, and whose cardinality allows the sequence to contain zero or one values. I will refer to such a construct as a
sequence type descriptor
, because the construct seems to need a name, and the XPath specification doesn't give it one.

Converting Atomic Values

The operation of converting an atomic value of one type into an atomic value of another type is called casting.

The word
casting
is used with the meaning that it has in SQL, which is subtly different from the usage in many other programming languages. In Java, casts perform a dual role: casting an Object is more like the
treat as
operator described later in this chapter, which doesn't actually change the value from one type to another. But casts in Java are also used for conversions among the primitive types, which is analagous to casting in XPath.

As well as an operator to perform a cast, XPath also provides a second operator to test whether a cast is possible. This has been provided because there is no way of recovering from the error that occurs when a cast fails (if, for example, you convert a string to a date and the string does not contain a valid date). Instead of attempting the cast and then dealing with the error when it fails, XPath encourages you first to test whether it will succeed and then to perform the conversion only if this is the case. So if
$p
is a user-supplied parameter that is supposed to contain a valid date, you can write:

Other books

Finding Purgatory by Kristina M. Sanchez
The Venus Trap by Voss, Louise
The Guardian by Beverly Lewis
SavageLust by Desiree Holt
Summer Ball by Mike Lupica
Call the Midlife by Chris Evans
Dawn of Fear by Susan Cooper
Always a Scoundrel by Suzanne Enoch
Day by A. L. Kennedy