Sequence Types

A sequence type is used in a query to specify the expected type of a sequence of zero, one, or more items. When declaring functions, sequence types are used to specify the types of the parameters as well as the return value. For example, the function declaration:

declare function local:getProdNums ($catalog as element( )) as xs:integer*
  {$catalog/product/xs:integer(number)};

uses two sequence types:

  • element( ), to specify that the $catalog parameter must be one (and only one) element

  • xs:integer*, to specify that the return type of the function is zero to many xs:integer values

Sequence types are also used in many type-related expressions, such as the cast as, treat as, and instance of expressions. The syntax of a sequence type is shown in Figure 11-2.

Syntax of a sequence typeThe detailed syntax of < element-attribute-test > is shown in Figure 13-4.

Figure 11-2. Syntax of a sequence type[a]

Occurrence Indicators

An occurrence indicator can be used at the end of a sequence type to indicate how many items can be in a sequence. The occurrence indicators are:

? For zero or one items

* For zero, one, or many items

+ For one or many items

If no occurrence indicator is specified, it is assumed that the sequence can have one and only one item. For example, a sequence type of xs:integer matches one and only one atomic value of type xs:integer. A sequence type of xs:string* matches a sequence that is either the empty sequence or contains one or more atomic values of type xs:string. A sequence type of node( )? matches either the empty sequence or a single node.

Remember that there is no difference between an item and a sequence that contains only that item. If a function expects xs:string* (a sequence of zero to many strings), it is perfectly acceptable to pass it a single string without attempting to enclose it in a sequence in any way.

The empty sequence, which is a sequence containing zero items, only matches sequence types that use the occurrence indicator ? or *, or empty-sequence( ).

Generic Sequence Types

Follwing are some generic sequence types:

item( )

Matches either a node or an atomic value of any type

node( )

Matches a node of any kind

empty-sequence( )

Matches the empty sequence

xs:anyAtomicType

Matches an atomic value

Table 11-2 shows some examples of the generic sequence types.

Table 11-2. Examples of generic sequence types

Example

Explanation

node( )*

A sequence of one or more nodes, or the empty sequence

item( )?

One item (a node or an atomic value) or the empty sequence

xs:anyAtomicType+

A sequence of one or more atomic values (of any type)

These generic sequence types are useful because it is not possible to specify, for example, "one or more xs:string values or nodes." In this case, you would instead need to specify a more generic sequence type, namely item( )+. They're also useful when defining generic functions such as reverse or count.

Atomic Type Names As Sequence Types

The sequence type can also be the qualified name of specific built-in or user-defined atomic types, such as xs:integer, xs:double, xs:date, xs:string, or prod:SizeType. This matches atomic values of that type or any type derived (directly or indirectly) from it. For example, the sequence type xs:integer also matches an atomic value of type xs:unsignedInt, because xs:unsignedInt is indirectly derived by restriction from xs:integer in the type hierarchy. The reverse is not true; the sequence type xs:unsignedInt does not match an xs:integer value; it must be explicitly cast.

These sequence types match atomic values only, not nodes that contain atomic values of the specified type.[*] An element that contains an integer would match element(*,xs:integer) (described in the next section) rather than xs:integer, for example. Table 11-3 shows some examples.

Table 11-3. Examples of sequence types based on type name

Example

Explanation

xs:integer

One atomic value of type xs:integer (or any type derived by restriction from xs:integer)

xs:integer?

One atomic value of type xs:integer (or any type derived by restriction from xs:integer), or the empty sequence

prod:NameType*

A sequence of one or more atomic values of type prod:NameType, or the empty sequence

Atomic types used in sequence type expressions must be in the in-scope schema definitions. This means that if it is not a built-in type, it must have been imported from a schema.

Element and Attribute Tests

The sequence types element( ) and attribute( ) can be used to match any one element or attribute (respectively). An alternate syntax, with the same meaning, uses an asterisk, as in element(*) and attribute(*).

It is also possible to test for a specific name. For example, the sequence type:

element(prod:product)

matches any element whose name is prod:product.

When schemas are used, it is also possible to test elements and attributes based on their type annotations in addition to their names. This is described in "Sequence Types and Schemas" in Chapter 13.

Sequence types can be used to test for other node kinds, using document-node( ), text( ), comment( ), and processing-instruction( ). These sequence types are discussed in Chapter 21.

Sequence Type Matching

Sequence type matching is the process of determining whether a sequence of one or more items matches a specified sequence type, according to the rules specified in the preceding sections. Several kinds of expressions perform sequence type matching, such as the instance of expression described in this section.

Additional static-typing-related expressions, described in Chapter 14, also use the rules for sequence type matching. The typeswitch expression uses sequence type matching to control which expressions are evaluated. Other expressions, namely FLWOR expressions and quantified expressions, allow a sequence type to be specified to test whether values bound to variables match a particular sequence type.

The "instance of" Expression

To determine whether a sequence of one or more items matches a particular sequence type, you can use an instance of expression, whose syntax is shown in Figure 11-3.

Syntax of an "instance of" expression

Figure 11-3. Syntax of an "instance of" expression

The instance of expression does not cast a value to the specified sequence type. It simply returns true or false, indicating whether the value matches that sequence type. Table 11-4 shows some examples of the instance of expression.

Table 11-4. Examples of "instance of" expressions

Example

Explanation

3 instance of xs:integer

true

3 instance of xs:decimal

true, because xs:integer is derived by restriction from xs:decimal

<x>{3}</x> instance of xs:integer

false, because the element node x is untyped, even though it happens to contain an integer

<x>{3}</x> instance of element( )

true

<x>{3}</x> instance of node( )

true

<x>{3}</x> instance of item( )

true

(3, 4, 5) instance of xs:integer

false

(3, 4, 5) instance of xs:integer*

true

xs:float(3) instance of xs:double

false

Sequence type matching does not include numeric type promotion. For this reason, the last example in the table returns false.



[a] The detailed syntax of < element-attribute-test > is shown in Figure 13-4.

[*] However, in function calls, nodes can be passed to functions expecting these kinds of atomic sequence types, because of atomization.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.0.145