Please check the errata for any errors or issues reported since publication.
See also translations.
This document is also available in these non-normative formats: XML.
Copyright © 2000 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
XPath 4.0 is an expression language that allows the processing of values conforming to the data model defined in [XDM 4.0]. The name of the language derives from its most distinctive feature, the path expression, which provides a means of hierarchic addressing of the nodes in an XML tree. As well as modeling the tree structure of XML, the data model also includes atomic items, function items, maps, arrays, and sequences. This version of XPath supports JSON as well as XML, and adds many new functions in [Functions and Operators 4.0].
XPath 4.0 is a superset of XPath 3.1. A detailed list of changes made since XPath 3.1 can be found in I Change Log.
This is a draft prepared by the QT4CG (officially registered in W3C as the XSLT Extensions Community Group). Comments are invited.
The publications of this community group are dedicated to our co-chair, Michael Sperberg-McQueen (1954–2024).
Michael was central to the development of XML and many related technologies. He brought a polymathic breadth of knowledge and experience to everything he did. This, combined with his indefatigable curiosity and appetite for learning, made him an invaluable contributor to our project, along with many others. We have lost a brilliant thinker, a patient teacher, and a loyal friend.
As noted in 2.1.3 Values, every value in XPath 4.0 is regarded as a sequence of zero, one, or more items. The type system of XPath 4.0, described in this section, classifies the kinds of value that the language can handle, and the operations permitted on different kinds of value.
The type system of XPath 4.0 is related to the type system of [XML Schema 1.0] or [XML Schema 1.1] in two ways:
atomic items in XPath 4.0 (which are one kind of item) have atomic types such as xs:string, xs:boolean, and xs:integer. These types are taken directly from their definitions in [XML Schema 1.0] or [XML Schema 1.1].
XNodes (which are another kind of item) have a property called a type annotation which determines the type of their content. The type annotation is a schema type. The type annotation of a node must not be confused with the item type of the node. For example, an element <age>23</age> might have been validated against a schema that defines this element as having xs:integer content. If this is the case, the type annotation of the node will be xs:integer, and in the XPath 4.0 type system, the node will match the item typeelement(age, xs:integer).
This chapter of the specification starts by defining sequence types and item types, which describe the range of values that can be bound to variables, used in expressions, or passed to functions. It then describes how these relate to schema types, that is, the simple and complex types defined in an XSD schema.
Note:
In many situations the terms item type and sequence type are used interchangeably to refer either to the type itself, or to the syntactic construct that designates the type: so in the expression $x instance of xs:string*, the construct xs:string* uses the SequenceType syntax to designate a sequence type whose instances are sequences of strings. When more precision is required, the specification is careful to use the terms item type and sequence type to refer to the actual types, while using the production names ItemType and SequenceType to refer to the syntactic designators of these types.
The term "function conversion rules" used in 3.1 has been replaced by the term "coercion rules". [ PR 254 29 November 2022]
The coercion rules allow “relabeling” of a supplied atomic item where the required type is a derived atomic type: for example, it is now permitted to supply the value 3 when calling a function that expects an instance of xs:positiveInteger. [Issue 117 PR 254 29 November 2022]
The coercion rules now allow any numeric type to be implicitly converted to any other, for example an xs:double is accepted where the required type is xs:decimal. [Issue 980 PR 911 30 January 2024]
The coercion rules now allow conversion in either direction between xs:hexBinary and xs:base64Binary. [Issues 130 480 PR 815 7 November 2023]
The coercion rules now apply recursively to the members of an array and the entries in a map. [Issue 1318 PR 1501 29 October 2024]
The coercion rules now reorder the entries in a map when the required type is a record type. [Issue 1862 PR 1874 25 March 2025]
[Definition: The coercion rules are rules used to convert a supplied value to a required type, for example when converting an argument of a function call to the declared type of the function parameter. ] The required type is expressed as a sequence type. The effect of the coercion rules may be to accept the value as supplied, to convert it to a value that matches the required type, or to reject it with a type error.
This section defines how the coercion rules operate; the situations in which the rules apply are defined elsewhere, by reference to this section.
Note:
In previous versions of this specification, the coercion rules were referred to as the function conversion rules. The terminology has changed because the rules are not exclusively associated with functions or function calling.
If the required type is empty-sequence(), no coercion takes place (the supplied value must be an empty sequence, or a type error occurs).
In all other cases, the required sequence typeT comprises a required item typeR and an optional occurrence indicator. The coercion rules are then applied to a supplied value V and the required type T as follows:
If XPath 1.0 compatibility mode is true and V is not an instance of the required type T, then the conversions defined in 3.4.1 XPath 1.0 Compatibility Rules are applied to V. Then:
Each item in V is processed against the required item type R using the item coercion rules defined in 3.4.2 Item Coercion Rules, and the results are sequence-concatenated into a single sequence V′.
A type error is raised if the cardinality of V′ does not match the required cardinality of T [err:XPTY0004].
The rules in this section are used to process each item J in a supplied sequence, given a required item typeR.
If R is a generalized atomic type (for example, if it is an atomic type, a pure union type, or an enumeration type), and J is not an atomic item, then:
J is atomizedatomized to produce a sequence of atomic items JJ.
Each atomic item in JJ is coerced to the required type R by recursive application of the item coercion rules (the rules in this section) to produce a value V.
The result is the sequence-concatenationsequence concatenation of the V values.
Note:
For example, if J is an element with type annotation xs:integer, and R is the union type xs:numeric, then the effect is to atomize the element to an xs:integer, and then to coerce the resulting xs:integer to xs:numeric (which leaves the integer unchanged). This is not the same as attempting to coerce the element to each of the alternatives of the union type in turn, which would deliver an instance of xs:double.
Otherwise, if R is a choice item type or a pure union type (which includes the case where it is an enumeration type), then:
If J matches (is an instance of) one of the alternatives in R, then J is coerced to the first alternative in R that J matches.
Note:
There are two situations where coercing an item to a type that it already matches does not simply return the item unchanged:
When the required type is a typed function type (see 3.2.8.1 Function Types), then function coercion is applied to coerce J to that function type, as described in 3.4.4 Function Coercion.
When the required type is a record type and the supplied value is a map, then coercion may change the entry orderDM of the entries in the map.
Otherwise, the item coercion rules (the rules in this section) are applied to J recursively with R set to each of the alternatives in the choice or union item type, in order, until an alternative is found that does not result in a type error; a type error is raised only if all alternatives fail.
The error code used in the event of failure should be the error code arising from the first unsuccessful matching attempt. (The diagnostic information associated with the error may also describe how further attempts failed.)
Note:
Suppose the required type is (xs:integer | element(e))* and the supplied value is the sequence (<e>22</e>, 23, <f>24</f>). Item coercion is applied independently to each of the three items in this sequence. The first item matches one of the alternatives, namely element(e), so it is returned unchanged as an element node. The second item (the integer 23) also matches one of the alternatives, and is returned unchanged as an integer. The third item does not match any of the alternatives, so coercion is attempted to each one in turn. Coercion to type xs:integer succeeds (by virtue of atomization and untyped atomic conversion), so the final result is the sequence (<e>22</e>, 23, 24)
Note:
Suppose the required type is enum("red", "green", "blue") and the supplied value is "green". The enumeration type is defined as a choice item type whose alternatives are singleton enumerations, so the rules are applied first to the type enum("red") (which fails), and then to the type enum("green") (which succeeds). The strings in an enumeration type are required to be distinct so the order of checking is in this case immaterial. The supplied value will be accepted, and will be relabeled if necessary as an instance of xs:string.
Note:
Schema-defined union types behave in exactly the same way as choice item types.
If R is an atomic type and J is an atomic item, then:
If J is an instance of R then it is used unchanged.
If J is an instance of type xs:untypedAtomic then:
If R is namespace-sensitive then a type error [err:XPTY0117] is raised.
Otherwise, J is cast to type R.
If there is an entry (from, to) in the following table such that J is an instance of from, and to is R, then J is cast to type R.
| from | to |
|---|---|
xs:decimal | xs:double |
xs:double | xs:decimal |
xs:decimal | xs:float |
xs:float | xs:decimal |
xs:float | xs:double |
xs:double | xs:float |
xs:string | xs:anyURI |
xs:anyURI | xs:string |
xs:hexBinary | xs:base64Binary |
xs:base64Binary | xs:hexBinary |
Note:
The item type in the to column must match R exactly; however, J may belong to a subtype of the type in the from column.
For example, an xs:NCName will be cast to type xs:anyURI, but an xs:anyURI will not be cast to type xs:NCName.
Similarly, an xs:integer will be cast to type xs:double, but an xs:double will not be cast to type xs:integer.
If R is an singleton enumeration type and J is an instance of xs:untypedAtomic or xs:anyURI, then J is cast to type xs:string.
Note:
The effect of this rule, when taken in conjunction with the rules above regarding atomization and choice item types, is that when the required type is based on an enumeration type, for example enum("red", "green", "blue")*, the supplied value can be, in this example:
An empty sequence.
The string "red".
An untyped node whose string value is "red".
A list-valued node whose typed value contains zero or more strings (or xs:anyURI values), each of which is codepoint-equal to one of "red", "green", or "blue".
The xs:anyURI value "red".
An array with zero or more members each of which is codepoint-equal to one of "red", "green", or "blue".
A JNode whose ·content· property is any of the above.
If R is derived from some primitive atomic type P, then J is relabeled as an instance of R if it satisfies all the following conditions:
J is an instance of P.
J is not an instance of R.
The datumDM of J is within the value space of R.
Relabeling an atomic item changes the type annotation but not the datumDM. For example, the xs:integer value 3 can be relabeled as an instance of xs:unsignedByte, because the datum is within the value space of xs:unsignedByte.
Note:
Relabeling is not the same as casting. For example, the xs:decimal value 10.1 can be cast to xs:integer, but it cannot be relabeled as xs:integer, because its datum not within the value space of xs:integer.
Note:
The effect of this rule is that if, for example, a function parameter is declared with an expected type of xs:positiveInteger, then a call that supplies the literal value 3 will succeed, whereas a call that supplies -3 will fail.
This differs from previous versions of this specification, where both these calls would fail.
This change allows the arguments of existing functions to be defined with a more precise type. For example, the $position argument of array:get could be defined as xs:positiveInteger rather than xs:integer.
Note:
If T is a union type with members xs:negativeInteger and xs:positiveInteger and the supplied value is the sequence (20, -20), then the effect of these rules is that the first item 20 is relabeled as type xs:positiveInteger and the second item -20is relabeled as type xs:negativeInteger.
Note:
Promotion (for example of xs:float to xs:double) occurs only when T is a primitive type. Relabeling occurs only when T is a derived type. Promotion and relabeling are therefore never combined.
Note:
A singleton enumeration type such as enum("green") is treated as an atomic type derived by restriction from xs:string; so if the xs:string value "green" is supplied in a context where the required type is enum("red", "green", "blue"), the value will be accepted.
If J is a JNodeDM and does not match R, then each item in the ·content· of J is coerced to type R by applying the coercion rules recursively.
Note:
For example, if $A is an array and the members of the array are maps, then $A/child::* returns a sequence of JNodes that encapsulate maps, and the average size of these maps can be obtained using the expression avg($A/child::* ! map:size(.)). The first argument of map:size does not accept a JNode directly, but it does (in effect) accept a JNode that encapsulates a map.
If R is an ArrayType other than array(*) and J is an array, then J is converted to a new array by converting each member to the required member type by applying the coercion rules recursively.
Note:
For example, if the required type is array(xs:double) and the supplied value is [ 1, 2 ], the array is converted to [ 1e0, 2e0 ].
If R is a MapType other than map(*) and J is a map, then J is converted to a new map as follows:
Each key in the supplied map is converted to the required map key type by applying the coercion rules. If the resulting map would contain duplicate keys, a type error is raised [err:XPTY0004].
The corresponding value is converted to the required map value type by applying the coercion rules recursively.
The order of entries in the map remains unchanged.
Note:
For example, if the required type is map(xs:string, xs:double) and the supplied value is { "x": 1, "y": 2 }, the map is converted to { "x": 1e0, "y": 2e0 }.
Note:
Duplicate keys can occur if the value space of the target type is more restrictive than the original type. For example, an error is raised if the map { 1.2: 0, 1.2000001: 0 }, which contains two keys of type xs:decimal, is coerced to the type map(xs:float, xs:integer).
If R is a RecordType and J is a map, then J is converted to a new map as follows:
The keys in the supplied map are unchanged.
In any map entry whose key is equal to the name of one of the field declarations in R (under the rules of the atomic-equal function), the corresponding value is converted to the required type defined by that field declaration, by applying the coercion rules recursively (but with XPath 1.0 compatibility mode treated as false).
The order of entries in the map is changed: entries whose keys correspond to the names of field declarations in R appear first, in the order of the corresponding field declarations, and (if the record type is extensible) other entries then follow retaining their relative order in J.
Note:
For example, if the required type is record(longitude as xs:double, latitude as xs:double) and the supplied value is { "latitude": 53.2, "longitude": 0 }, then the map is converted to { "longitude": 0.0e0, "latitude": 53.2e0 }.
If R is a TypedFunctionType and J is a function item, then function coercion is applied to J.
Note:
Function coercion applies even if J is already an instance of R.
Maps and arrays are functions, so function coercion applies to them as well.
If, after the above conversions, the resulting item does not match the expected item type R according to the rules for SequenceType Matching, a type error is raised [err:XPTY0004].
Note:
Under the general rules for type errors (see 2.4.1 Kinds of Errors), a processor may report a type error during static analysis if it will necessarily occur when the expression is evaluated. For example, the function call fn:abs("beer") will necessarily fail when evaluated, because the function requires a numeric value as its argument; this may be detected and reported as a static error.