18 Constructor functions

This section describes constructor functions corresponding to simple types defined in [XML Schema Part 2: Datatypes Second Edition]. Constructor functions are used to convert a supplied value to a given type. They always take a single argument, and the name of the function is the same as the name of the target type.

Constructor functions are defined for all user-defined named simple types, and for most built-in atomic, list, and union types. The only named simple types that have no constructor function are those that have no instances other than instances of their derived types: specifically, xs:anySimpleType, xs:anyAtomicType, and xs:NOTATION.

18.1 Constructor functions for XML Schema built-in atomic types

Every built-in atomic type that is defined in [XML Schema Part 2: Datatypes Second Edition], except xs:anyAtomicType and xs:NOTATION, has an associated constructor function. The type xs:untypedAtomic, defined in Section 2.7 Schema Information DM31 and the two derived types xs:yearMonthDuration and xs:dayTimeDuration defined in Section 2.7 Schema Information DM31 also have associated constructor functions. Implementations may additionally provide a constructor functions for the new datatype xs:dateTimeStamp introduced in [Schema 1.1 Part 2].

A constructor function is not defined for xs:anyAtomicType as there are no atomic values with type annotation xs:anyAtomicType at runtime, although this can be a statically inferred type. A constructor function is not defined for xs:NOTATION since it is defined as an abstract type in [XML Schema Part 2: Datatypes Second Edition]. If the static context (See Section 2.1.1 Static Context XP31) contains a type derived from xs:NOTATION then a constructor function is defined for it. See 18.5 Constructor functions for user-defined types.

The form of the constructor function for an atomic type eg:TYPE is:

eg:TYPE(
$arg as xs:anyAtomicType
) as eg:TYPE?

If $arg is the empty sequence, the empty sequence is returned. For example, the signature of the constructor function corresponding to the xs:unsignedInt type defined in [XML Schema Part 2: Datatypes Second Edition] is:

xs:unsignedInt(
$arg as xs:anyAtomicType
) as xs:unsignedInt?

Calling the constructor function xs:unsignedInt(12) returns the xs:unsignedInt value 12. Another call of that constructor function that returns the same xs:unsignedInt value is xs:unsignedInt("12"). The same result would also be returned if the constructor function were to be called with a node that had a typed value equal to the xs:unsignedInt 12. The standard features described in Section 2.4.2 Atomization XP31 would atomize the node to extract its typed value and then call the constructor with that value. If the value passed to a constructor is not in the lexical space of the datatype to be constructed, and cannot be converted to a value in the value space of the datatype under the rules in this specification, then an dynamic error is raised [err:FORG0001].

The semantics of the constructor function xs:TYPE(arg) are identical to the semantics of arg cast as xs:TYPE? . See 19 Casting.

If the argument to a constructor function is a literal, the result of the function may be evaluated statically; if an error is found during such evaluation, it may be reported as a static error.

Special rules apply to constructor functions for xs:QName and types derived from xs:QName and xs:NOTATION. See 18.2 Constructor functions for xs:QName and xs:NOTATION.

The following constructor functions for the built-in atomic types are supported:

18.2 Constructor functions for xs:QName and xs:NOTATION

Special rules apply to constructor functions for the types xs:QName and xs:NOTATION, for two reasons:

These constraints result in the following rules:

  1. There is no constructor function for xs:NOTATION. Constructors are defined, however, for xs:QName, for types derived or constructed from xs:QName, and for types derived or constructed from xs:NOTATION.

  2. When converting from an xs:string, the prefix within the lexical xs:QName supplied as the argument is resolved to a namespace URI using the statically known namespaces from the static context. If the lexical xs:QName has no prefix, the namespace URI of the resulting expanded-QName is the default element/type namespace from the static context. Components of the static context are defined in Section 2.1.1 Static Context XP31. A dynamic error is raised [err:FONS0004] if the prefix is not bound in the static context. As described in Section 2.1 Terminology DM31, the supplied prefix is retained as part of the expanded-QName value.

When a constructor function for a namespace-sensitive type is used as a literal function item or in a partial function application (for example, xs:QName#1 or xs:QName(?)) the namespace bindings that are relevant are those from the static context of the literal function item or partial function application. When a constructor function for a namespace-sensitive type is obtained by means of the fn:function-lookup function, the relevant namespace bindings are those from the static context of the call on fn:function-lookup.

Note:

When the supplied argument to the xs:QName constructor function is a node, the node is atomized in the usual way, and if the result is xs:untypedAtomic it is then converted as if a string had been supplied. The effect might not be what is desired. For example, given the attribute xsi:type="my:type", the expression xs:QName(@xsi:type) might fail on the grounds that the prefix my is undeclared. This is because the namespace bindings are taken from the static context (that is, from the query or stylesheet), and not from the source document containing the @xsi:type attribute. The solution to this problem is to use the function call resolve-QName(@xsi:type, .) instead.

18.3 Constructor functions for XML Schema built-in list types

Each of the three built-in list types defined in [XML Schema Part 2: Datatypes Second Edition], namely xs:NMTOKENS, xs:ENTITIES, and xs:IDREFS, has an associated constructor function.

The function signatures are as follows:

The semantics are equivalent to casting to the corresponding types from xs:string.

All three of these types have the facet minLength = 1 meaning that there must always be at least one item in the list. The return type, however, allows for the fact that when the argument to the function is an empty sequence, the result is an empty sequence.

Note:

In the case of atomic types, it is possible to use an expression such as xs:date(@date-of-birth) to convert an attribute value to an instance of xs:date, knowing that this will work both in the case where the attribute is already annotated as xs:date, and also in the case where it is xs:untypedAtomic. This approach does not work with list types, because it is not permitted to use a value of type xs:NMTOKEN* as input to the constructor function xs:NMTOKENS. Instead, it is necessary to use conditional logic that performs the conversion only in the case where the input is untyped: if (@x instance of attribute(*, xs:untypedAtomic)) then xs:NMTOKENS(@x) else data(@x)

18.4 Constructor functions for XML Schema built-in union types

There is a constructor function for the union type xs:numeric defined in [XQuery and XPath Data Model (XDM) 3.1]. The function signature is:

The semantics are determined by the rules in 19.3.5 Casting to union types. These rules have the effect that:

  1. If the argument is an instance of xs:double, xs:float, or xs:decimal, then the result is an instance of the same primitive type, with the same value;

  2. If the argument is an instance of xs:boolean, the result is the xs:double value 0.0e0 or 1.0e0;

  3. If the argument is an instance of xs:string or xs:untypedAtomic, then:

    1. If the value is in the lexical space of xs:double, the result will be the corresponding xs:double value;

    2. Otherwise, a dynamic error [err:FORG0001] occurs;

    Note:

    The result will never be an instance of xs:float, xs:decimal, or xs:integer. This is because xs:double appears first in the list of member types of xs:numeric, and its lexical space subsumes the lexical space of the other numeric types. Thus, unlike XPath numeric literals, the result does not depend on the lexical form of the supplied value. The reason for this design choice is to retain compatibility with the function conversion rules: functions such as fn:abs and fn:round are declared to expect an instance of xs:numeric as their first or only argument, and compatibility with the function conversion rules defined in earlier versions of these specifications demands that when an untyped atomic value (or untyped node) is supplied as the argument, it is converted to an xs:double value even if its lexical form is that (say) of an integer.

  4. In all other cases, a dynamic error [err:FORG0001] occurs.

In the case of an implementation that supports XSD 1.1, there is a constructor function associated with the built-in union type xs:error.

The function signature is as follows:

The semantics are equivalent to casting to the corresponding union type (see 19.3.5 Casting to union types).

Note:

Because xs:error has no member types, and therefore has an empty value space, casting will always fail with a dynamic error except in the case where the supplied argument is an empty sequence, in which case the result is also an empty sequence.

18.5 Constructor functions for user-defined types

For every user-defined simple type in the static context (See Section 2.1.1 Static Context XP31), there is a constructor function whose name is the same as the name of the type and whose effect is to create a value of that type from the supplied argument. The rules for constructing user-defined types are defined in the same way as the rules for constructing built-in derived types defined in 18.1 Constructor functions for XML Schema built-in atomic types.

Special rules apply to constructor functions for namespace-sensitive types, that is, atomic types derived from xs:QName and xs:NOTATION, list types that have a namespace-sensitive item type, and union types that have a namespace-sensitive member type. See 18.2 Constructor functions for xs:QName and xs:NOTATION.

Consider a situation where the static context contains an atomic type called hatSize defined in a schema whose target namespace is bound to the prefix eg. In such a case the following constructor function is available to users:

eg:hatSize(
$arg as xs:anyAtomicType
) as my:hatSize?

In the case of an atomic type A, the return type of the function is A?, reflecting the fact that the result will be an empty sequence if the input is an empty sequence. For a union or list type, the return type of the function is specified only as xs:anyAtomicType*. Implementations performing static type checking will often be able to compute a more specific result type. For example, if the target type is a list type whose item type is the atomic type A, the result will always be an instance of A*; if the target type is a pure union type U then the result will always be an instance of U?. In general, however, applications needing interoperable behavior on implementations that do strict static type checking will need to use a treat as expression to assert the specific type of the result.

To construct an instance of a user-defined type that is not in a namespace, it is possible to use an EQName (for example Q{}hatsize(17)). Alternatives are to use a cast expression (17 cast as hatsize) or (if the host language allows it) to undeclare the default function namespace.