Castable expressions

Castable expressions test whether a value can be cast to a specific data type. If the value can be cast to the data type, the castable expression returns true. Otherwise, the expression returns false.

Castable expressions can be used as predicates to avoid cast errors at evaluation time. They can also be used to select an appropriate type for processing a value. For information about which types can be cast to which other types, see Type casting.

Syntax

Read syntax diagramSkip visual syntax diagramExpression castable asTargetType?
Expression
An XQuery expression that returns a single atomic value or an empty sequence.
TargetType
The type used to test if the value of Expression can be cast. TargetType must be an atomic type that is one of the predefined XML schema types. The data types xs:NOTATION, xdt:anyAtomicType, and xs:anySimpleType are not valid types for TargetType.
?
Indicates that an empty sequence is considered a valid instance of the target type. If Expression evaluates to an empty sequence and ? is not specified, the castable expression returns False.

Returned value

If Expression can be cast to TargetType, the castable expression returns true. Otherwise, the expression returns false.

If the result of Expression is an empty sequence and the question mark indicator follows TargetType, the castable expression returns true. In the following example, the question mark indicator follows the target type xs:integer.

$prod/revision castable as xs:integer?

If TargetType of a castable expression is xs:QName, or a type derived from xs:QName or xs:NOTATION, and Expression is of type xs:string but it is not a literal string, the returned value of the castable expression is false.

If the result of Expression is a sequence of more than one atomic value, an error is returned.

Examples

The following example uses the castable expression as a predicate to avoid errors at evaluation time. The following example avoids a dynamic error if @OrderDate is not a valid date.

$po/orderID[if ( $po/@OrderDate castable as xs:date)
   then xs:date($po/@OrderDate) gt xs:date("2000-01-01")
   else false()]

The predicate is true and returns the orderID only if the date attribute is a valid date greater than January 1, 2000. Otherwise, the predicate is false and returns an empty sequence.

The following example uses the castable expression to select an appropriate type for processing of a given value. The example uses castable to cast a postal code as either an integer or a string:

if ($postalcode castable as xs:integer)
   then $postalcode cast as xs:integer
   else $postalcode cast as xs:string

The following example uses the castable expression in the FLWOR let clause to test the value of $prod/mfgdate and bind a value to $currdate. The castable expression and the cast expression support processing an empty sequence using the question mark indicator.

let $currdate := if ($prod/mfgdate castable as xs:date?)
   then $prod/mfgdate cast as xs:date?
   else "1000-01-01" cast as xs:date

If the value of $prod/mfgdate can be cast as xs:date, it is cast to the data type and is bound to $currdate. If $prod/mfgdate is an empty sequence, an empty sequence is bound to $currdate. If $prod/mfgdate cannot be cast as xs:date, a value of 1000-01-01 of type xs:date is bound to $currdate.

The following example uses the castable expression to test the value of the product category before performing a comparison. In the XML column FEATURES.INFO, the documents contain the element /prod/category. The value is either a numeric code or string code. The castable expressions in the XMLEXISTS predicate tests the value of /prod/category before performing a comparison to avoid errors at evaluation time.

SELECT F.PRODID FROM F FEATURES
WHERE xmlexists('$test/prod/category[ (( . castable as xs:double) and . > 100 ) or
   (( . castable as xs:string) and . > "A100" )]'
   passing F.INFO as "test")

The returned values are product IDs where the category codes are either greater than the number 100 or greater than the string "A100."