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:
-
xs:string ( |
$arg |
as xs:anyAtomicType |
|
) as xs:string? |
-
xs:boolean ( |
$arg |
as xs:anyAtomicType |
|
) as xs:boolean? |
-
xs:decimal ( |
$arg |
as xs:anyAtomicType |
|
) as xs:decimal? |
-
xs:float ( |
$arg |
as xs:anyAtomicType |
|
) as xs:float? |
Implementations should return negative zero for xs:float("-0.0E0")
.
But because [XML Schema Part 2: Datatypes Second Edition] does not distinguish between the values positive zero and negative zero,
implementations may return positive zero in this case.
-
xs:double ( |
$arg |
as xs:anyAtomicType |
|
) as xs:double? |
Implementations should return negative zero for xs:double("-0.0E0")
.
But because [XML Schema Part 2: Datatypes Second Edition] does not distinguish between the values positive zero and negative zero,
implementations may return positive zero in this case.
-
xs:duration ( |
$arg |
as xs:anyAtomicType |
|
) as xs:duration? |
-
xs:dateTime ( |
$arg |
as xs:anyAtomicType |
|
) as xs:dateTime? |
-
xs:time ( |
$arg |
as xs:anyAtomicType |
|
) as xs:time? |
-
xs:date ( |
$arg |
as xs:anyAtomicType |
|
) as xs:date? |
-
xs:gYearMonth ( |
$arg |
as xs:anyAtomicType |
|
) as xs:gYearMonth? |
-
xs:gYear ( |
$arg |
as xs:anyAtomicType |
|
) as xs:gYear? |
-
xs:gMonthDay ( |
$arg |
as xs:anyAtomicType |
|
) as xs:gMonthDay? |
-
xs:gDay ( |
$arg |
as xs:anyAtomicType |
|
) as xs:gDay? |
-
xs:gMonth ( |
$arg |
as xs:anyAtomicType |
|
) as xs:gMonth? |
-
xs:hexBinary ( |
$arg |
as xs:anyAtomicType |
|
) as xs:hexBinary? |
-
xs:base64Binary ( |
$arg |
as xs:anyAtomicType |
|
) as xs:base64Binary? |
-
xs:anyURI ( |
$arg |
as xs:anyAtomicType |
|
) as xs:anyURI? |
-
xs:QName ( |
$arg |
as xs:anyAtomicType |
|
) as xs:QName? |
See 18.2 Constructor functions for xs:QName and xs:NOTATION for special rules.
-
xs:yearMonthDuration ( |
$arg |
as xs:anyAtomicType |
|
) as xs:yearMonthDuration? |
-
xs:dayTimeDuration ( |
$arg |
as xs:anyAtomicType |
|
) as xs:dayTimeDuration? |
-
xs:untypedAtomic ( |
$arg |
as xs:anyAtomicType |
|
) as xs:untypedAtomic? |
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:
-
Values cannot belong directly to the type xs:NOTATION
, only to its subtypes.
-
The lexical representation of these types uses namespace prefixes, whose
meaning is context-dependent.
These constraints result in the following rules:
-
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
.
-
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:
-
xs:NMTOKENS ( |
$arg |
as xs:anyAtomicType |
|
) as xs:NMTOKEN* |
-
xs:ENTITIES ( |
$arg |
as xs:anyAtomicType |
|
) as xs:ENTITY* |
-
xs:IDREFS ( |
$arg |
as xs:anyAtomicType |
|
) as xs:IDREF* |
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:
-
xs:numeric ( |
$arg |
as xs:anyAtomicType |
|
) as xs:numeric? |
The semantics are determined by the rules in 19.3.5 Casting to union types. These rules have the effect that:
-
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;
-
If the argument is an instance of xs:boolean
, the result is the xs:double
value
0.0e0
or 1.0e0
;
-
If the argument is an instance of xs:string
or xs:untypedAtomic
, then:
-
If the value is in the lexical space of xs:double
, the result will be the
corresponding xs:double
value;
-
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.
-
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:
-
xs:error ( |
$arg |
as xs:anyAtomicType |
|
) as xs:error? |
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.