Choice item types

A construct of the form (type1 | type2 | type3) can be used to define unions of arbitrary types. That is, a parenthesized sequence of item types separated by |. For example, (xs:base64Binary | xs:hexBinary) defines a choice type whose members are xs:base64Binary and xs:hexBinary, while (xs:date | xs:time | xs:dateTime) defines a choice type whose members are xs:date, xs:time, and xs:dateTime. These types can conveniently be used in function signatures when writing a function that is designed to take arguments of more than one type.

The member types do not need to be atomic; for example (map(*) | array(*)) is a type that matches maps and arrays, while (document-node() | element()) matches either a document or element node.

If the member types are atomic, then the choice type follows very similar rules to a schema-defined union type: in particular, the order of member type names is significant, and determines the order used for casting or validating strings.

This construct can be used anywhere that an item type is recognized, for example in instance of expressions, in the as attribute of variable and function declarations, or in XQuery typeswitch expressions. It can be used as the target of a cast as or castable as expression only if all the member types are atomic.

For example, the following code defines an XQuery function that formats a date, time, dateTime, or a string in the form of a date, time, or dateTime using the appropriate variant of the format-date/time function:

declare function local:format( $in as (xs:dateTime | xs:date | xs:time | xs:string), $fmt as xs:string) as xs:string { typeswitch ($in) case xs:dateTime return format-dateTime($in, $fmt) case xs:date return format-date($in, $fmt) case xs:time return format-time($in, $fmt) case xs:string return local:format($in cast as (xs:dateTime | xs:date | xs:time), $fmt) default return error() }; local:format("2016-10-07", $fmt)

Choice item types can also be used in XSLT match patterns, using the type pattern syntax ~T. For example a template defined with match="~(xs:date | xs:time)" will match values of those types.