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.
XML is a versatile markup language, capable of labeling the information content of diverse data sources, including structured and semi-structured documents, relational databases, and object repositories. A query language that uses the structure of XML intelligently can express queries across all these kinds of data, whether physically stored in XML or viewed as XML via middleware. This specification describes a query language called XQuery, which is designed to be broadly applicable across many types of XML data sources.
A list of changes made since XQuery 3.1 can be found in J Change Log.
This section describes the status of this document at the time of its publication. Other documents may supersede this document.
This document is a working draft developed and maintained by a W3C Community Group, the XQuery and XSLT Extensions Community Group unofficially known as QT4CG (where "QT" denotes Query and Transformation). This draft is work in progress and should not be considered either stable or complete. Standard W3C copyright and patent conditions apply.
The community group welcomes comments on the specification. Comments are best submitted as issues on the group's GitHub repository.
As the Community Group moves towards publishing dated, stable drafts, some features that the group thinks may likely be removed or substantially changed are marked “at risk” in their changes section. In this draft:
The community group maintains two extensive test suites, one oriented to XQuery and XPath, the other to XSLT. These can be found at qt4tests and xslt40-test respectively. New tests, or suggestions for correcting existing tests, are welcome. The test suites include extensive metadata describing the conditions for applicability of each test case as well as the expected results. They do not include any test drivers for executing the tests: each implementation is expected to provide its own test driver.
The publications of this community group are dedicated to our co-chair, Michael Sperberg-McQueen (1954–2024).
The basic building block of XQuery 4.0 is the expression, which is a string of [Unicode] characters; the version of Unicode to be used is implementation-defined. The language provides several kinds of expressions which may be constructed from keywords, symbols, and operands. In general, the operands of an expression are other expressions. XQuery 4.0 allows expressions to be nested with full generality. (However, unlike a pure functional language, it does not allow variable substitution if the variable declaration contains construction of new nodes.)
Note:
This specification contains no assumptions or requirements regarding the character set encoding of strings of [Unicode] characters.
Like XML, XQuery 4.0 is a case-sensitive language. Keywords in XQuery 4.0 use lower-case characters and are not reserved—that is, names in XQuery 4.0 expressions are allowed to be the same as language keywords, except for certain unprefixed function-names listed in A.4 Reserved Function Names.
In this specification the phrases must, must not, should, should not, may, required, and recommended, when used in normative text and rendered in small capitals, are to be interpreted as described in [RFC2119].
Certain aspects of language processing are described in this specification as implementation-defined or implementation-dependent.
[Definition: Implementation-defined indicates an aspect that may differ between implementations, but must be specified by the implementer for each particular implementation.]
[Definition: Implementation-dependent indicates an aspect that may differ between implementations, is not specified by this or any W3C specification, and is not required to be specified by the implementer for any particular implementation.]
Changes in 4.0 (next | previous)
The term atomic value has been replaced by atomic item. [Issue 1337 PR 1361 2 August 2024]
The terms XNode and JNode are introduced; the existing term node remains in use as a synonym for XNode where the context does not specify otherwise. [Issue 2025 PR 2031 13 June 2025]
[Definition: In the data model, a value is always a sequence.]
[Definition: A sequence is an ordered collection of zero or more items.]
[Definition: An item is either an atomic item, a node, or a function item.]
[Definition: An atomic item is a value in the value space of an atomic type, as defined in [XML Schema 1.0] or [XML Schema 1.1].]
[Definition: An XNode is an instance of one of the node kinds defined in [XDM 4.0] section 7.1 XML Nodes.] Each XNode has a unique node identity, a typed value, and a string value. In addition, some XNodes have a name. The typed value of an XNode is a sequence of zero or more atomic items. The string value of an XNode is a value of type xs:string. The name of an XNode is a value of type xs:QName.
[Definition: Except where the context indicates otherwise, the term node is used as a synonym for XNode.]
[Definition: A JNode (see also [XDM 4.0] section 8.4 JNodes) is an encapsulation of a value as it appears within a tree of maps and arrays, typically (but not necessarily) obtained by parsing JSON texts.]
[Definition: A GNode (for generalized node) is either an XNode or a JNode.]
[Definition: A function item is an item that can be called using a dynamic function call.]
Maps (see 4.14.1 Maps) and arrays (see 4.14.2 Arrays) are specific kinds of function items.
[Definition: A sequence containing exactly one item is called a singleton.] An item is identical to a singleton sequence containing that item. Sequences are never nested—for example, combining the values 1, (2, 3), and ( ) into a single sequence results in the sequence (1, 2, 3). [Definition: AThe sequence containing zero items is called anthe empty sequence.]
[Definition: The term XDM instance is used, synonymously with the term value, to denote an unconstrained sequence of items.]
The XPath, XQuery, and XSLT languages provide a number of capabilities to access external resources. These include:
Functions such as doc, doc-available, unparsed-text, unparsed-text-lines, unparsed-text-available, collectionuri-collection, and unparsed-binary, and in XSLT, the document function and the xsl:source-document and xsl:merge instructions.
Static inclusion of code using import module in XQuery, or xsl:include, xsl:import, and xsl:use-package in XSLT.
Dynamic inclusion and execution of external code using the functions transform and load-xquery-module, and in XSLT, the xsl:evaluate instruction.
The ability to write to external resources using the xsl:result-document instruction in XSLT, or the put function in the XQuery Update Facility.
The ability to invoke arbitrary user-defined external functions (called extension functions in XSLT).
The ability to invoke vendor-defined external/extension functions; a notable example being the EXPath File library.
Access to environment variables and system properties using functions such as environment-variable, available-environment-variables, and (in XSLT) system-property.
Static inclusion of XSD schemas and schema documents using import schemain XQuery or xsl:import-schema in XSLT, or indirectly using xs:import, xs:include, xs:redefine, or xs:override in XSD schema documents.
Dynamic loading of XSD schema documents (directly or indirectly) using the xsd-validator function.
The ability to parse XML or HTML documents that contain references to external entities, for example by using the parse-xml and parse-html functions.
The ability to parse XML documents in a way that causes other external resources to be fetched, for example by activating XInclude, or by performing XSD validation using xsi:schema-location.
Implicit access to third-party libraries supporting (for example) collations or localization.
External resources are always referenced by means of a URI. The way in which a URI is dereferenced to obtain a resource is implementation defined. It is recommended that popular URI schemes such as http, https, and file should be supported, but this may be subject to user configuration and security constraints. Implementations are free to support indirection mechanisms such as catalogs and resolver callbacks, as well as supporting additional URI schemes and protocols, whether standardized or not.
[Definition: The static context includes a boolean property called trusted that determines whether external resources are available.] This may take the following values:
false: No external resources are available other than resources explicitly made available by the caller through some trusted implementation-defined mechanism.
[Definition: ]Code executing with trusted set to false is said to be untrusted.
true: Trusted code has access to all the resources available to its immediate caller.
The functions transform and load-xquery-module, and the XSLT instruction xsl:evaluate, have an option allowing the trust level of the executed code to be set:
If trusted is set to true, the invoked code executes with the same trust level as its caller.
If trusted is set to false, the invoked code is not able to access any external resources other than resources explicitly made available using an implementation defined mechanism under the control of the caller.
Some resources, such as XML documents, may themselves contain references to other resources. For example, an XML document may reference external entities (including an external DTD). External entity expansion is recognized as a known security risk. Functions that invoke XML parsing (such as parse-xml, doc, or collection) therefore have a trusted option indicating whether the document being parsed is trusted to access external entities. Such access is allowed only if (a) the trusted option is set to true, or (b) access to the external entity in question is explicitly enabled by the caller.
Note:
The term explicitly enabled is not intended to mean that every resource to which access is permitted must be individually listed. The mechanism for enabling access might provide access to a class of resources (for example, all resources accessible using the HTTPS protocol, or all resources within the containing XML database having particular access permissions). The mechanism might also take account of other criteria, for example it might impose limits on the size or other characteristics of the resources accessed.
It is recommended that any external API used to invoke XPath, XQuery, or XSLT processing should similarly offer the ability to indicate whether the code being executed is trusted.
In the interests of security, the default for these options is false. However, for backwards compatibility reasons, processors may provide an option whereby a trusted user can change the default.
In general, when an application requests access to an external resource which is not available because the application is untrusted, the processor should behave in the same way as if the resource did not exist. However, the processor may choose to disclose in its diagnostics why the request was unsuccessful.
A processor may (but is not required to) limit an application’s consumption of resources such as CPU cycles and memory when the application is untrusted.
[Definition: The term available documents refers (TODO: for the time being) to the set of XML documents that an application is able to access by URI.]
The semantics of XQuery 4.0 are defined in terms of the data model and the expression context.
Figure 1: Processing Model Overview
Figure 1 provides a schematic overview of the processing steps that are discussed in detail below. Some of these steps are completely outside the domain of XQuery 4.0; in Figure 1, these are depicted outside the line that represents the boundaries of the language, an area labeled external processing. The external processing domain includes generation of XDM instances that represent the data to be queried (see 2.4.1 Data Model Generation), schema import processing (see 2.4.2 Schema Import Processing), and serialization (see 2.4.5 Serialization). The area inside the boundaries of the language is known as the query processing domain, which includes the static analysis and dynamic evaluation phases (see 2.4.3 Expression Processing). Consistency constraints on the query processing domain are defined in 2.4.6 Consistency Constraints.
XQuery 4.0 defines two phases of processing called the static analysis phase and the dynamic evaluation phase (see Figure 1). During the static analysis phase, static errors, dynamic errors, or type errors may be raised. During the dynamic evaluation phase, only dynamic errors or type errors may be raised. These kinds of errors are defined in 2.5.1 Kinds of Errors.
Within each phase, an implementation is free to use any strategy or algorithm whose result conforms to the specifications in this document.
[Definition: The static analysis phase depends on the expression itself and on the static context. The static analysis phase does not depend on input data (other than schemas).]
During the static analysis phase, the query is typically parsed into an internal representation called the operation tree (step SQ1 in Figure 1). A parse error is raised as a static error [err:XPST0003]. The static context is initialized by the implementation (step SQ2). The static context is then changed and augmented based on information in the prolog (step SQ3). The static context is extended with function declarations and variable declarations from imported modules. If the Schema Aware Feature is supported, the in-scope schema definitions are populated with information from imported schemas. The static context is used to resolve schema type names, function names, namespace prefixes, and variable names (step SQ4). If a name of one of these kinds in the operation tree is not found in the static context, a static error ([err:XPST0008] or [err:XPST0017]) is raised (however, see exceptions to this rule in 3.2.7.2 Element Types and 3.2.7.3 Attribute Types.)
The operation tree is then typically normalized by making explicit the implicit operations such as atomization and extraction of effective boolean values (step SQ5).
During the static analysis phase, a processor may perform type analysis. The effect of type analysis is to assign a static type to each expression in the operation tree. [Definition: The static type of an expression is the best inference that the processor is able to make statically about the type of the result of the expression.] This specification does not define the rules for type analysis nor the static types that are assigned to particular expressions: the only constraint is that the inferred type must match all possible values that the expression is capable of returning.
Examples of inferred static types might be:
For the expression concat(a,b) the inferred static type is xs:string
For the expression $a = $v the inferred static type is xs:boolean
For the expression $s[exp] the inferred static type has the same item type as the static type of $s, but a cardinality that allows the empty sequence even if the static type of $s does not allow anthe empty sequence.
The inferred static type of the expression data($x) (whether written explicitly or inserted into the operation tree in places where atomization is implicit) depends on the inferred static type of $x: for example, if $x has type element(*, xs:integer) then data($x) has static type xs:integer.
In XQuery 1.0 and XPath 2.0, rules for static type inferencing were published normatively in [XQuery 1.0 and XPath 2.0 Formal Semantics], but implementations were allowed to refine these rules to infer a more precise type where possible. In subsequent versions, the rules for static type inferencing are entirely implementation-dependent.
Every kind of expression also imposes requirements on the type of its operands. For example, with the expression substring($a, $b, $c), $a must be of type xs:string (or something that can be converted to xs:string by the function calling rules), while $b and $c must be numeric.
A processor may raise a type error during static analysis if the inferred static type of an expression has no overlap (intersection) with the required type, and cannot be converted to the required type using the coercion rules. For example, given the call fn:upper-case($s), the processor may raise an error if the declared or inferred type of $s is xs:integer, but not if it is xs:anyAtomicType.
In addition, type analysis may conclude that an expression is implausible. Implausible expressions may be considered erroneous unless such checks have been disabled. For example, the expression round(tokenize($input)) is implausible because the required type for fn:round is xs:numeric?, while the static type of tokenize($input) is xs:string*, and these two sequence types are substantively disjoint. This topic is described further in 2.5.6 Implausible Expressions.
Alternatively, the processor may defer all type checking until the dynamic evaluation phase.
Because different implementations may choose to evaluate or optimize an expression in different ways, certain aspects of raising dynamic errors are implementation-dependent, as described in this section.
An implementation is always free to evaluate the operands of an operator in any order.
In some cases, a processor can determine the result of an expression without accessing all the data that would be implied by the formal expression semantics. For example, the formal description of filter expressions suggests that $s[1] should be evaluated by examining all the items in sequence $s, and selecting all those that satisfy the predicate position()=1. In practice, many implementations will recognize that they can evaluate this expression by taking the first item in the sequence and then exiting. If $s is defined by an expression such as //book[author eq 'Berners-Lee'], then this strategy may avoid a complete scan of a large document and may therefore greatly improve performance. However, a consequence of this strategy is that a dynamic error or type error that would be detected if the expression semantics were followed literally might not be detected at all if the evaluation exits early. In this example, such an error might occur if there is a book element in the input data with more than one author subelement.
The extent to which a processor may optimize its access to data, at the cost of not raising errors, is defined by the following rules.
Consider an expression Q that has an operand (sub-expression) E. In general the value of E is a sequence. At an intermediate stage during evaluation of the sequence, some of its items will be known and others will be unknown. If, at such an intermediate stage of evaluation, a processor is able to establish that there are only two possible outcomes of evaluating Q, namely the value V or an error, then the processor may deliver the result V without evaluating further items in the operand E. For this purpose, two values are considered to represent the same outcome if their items are pairwise the same, where nodes are the same if they have the same identity, and values are the same if they are equal and have exactly the same type.
There is an exception to this rule: If a processor evaluates an operand E (wholly or in part), then it is required to establish that the actual value of the operand E does not violate any constraints on its cardinality. For example, the expression $e eq 0 results in a type error if the value of $e contains two or more items. A processor is not allowed to decide, after evaluating the first item in the value of $e and finding it equal to zero, that the only possible outcomes are the value true or a type error caused by the cardinality violation. It must establish that the value of $e contains no more than one item.
These rules apply to all the operands of an expression considered in combination: thus if an expression has two operands E1 and E2, it may be evaluated using any samples of the respective sequences that satisfy the above rules.
The rules cascade: if A is an operand of B and B is an operand of C, then the processor needs to evaluate only a sufficient sample of B to determine the value of C, and needs to evaluate only a sufficient sample of A to determine this sample of B.
The effect of these rules is that the processor is free to stop examining further items in a sequence as soon as it can establish that further items would not affect the result except possibly by causing an error. For example, the processor may return true as the result of the expression S1 = S2 as soon as it finds a pair of equal values from the two sequences.
Another consequence of these rules is that where none of the items in a sequence contributes to the result of an expression, the processor is not obliged to evaluate any part of the sequence. Again, however, the processor cannot dispense with a required cardinality check: if anthe empty sequence is not permitted in the relevant context, then the processor must ensure that the operand is not anthe empty sequence.
Examples:
If an implementation can find (for example, by using an index) that at least one item returned by $expr1 in the following example has the value 47, it is allowed to return true as the result of the some expression, without searching for another item returned by $expr1 that would raise an error if it were evaluated.
some $x in $expr1 satisfies $x = 47
In the following example, if an implementation can find (for example, by using an index) the product element-nodes that have an id child with the value 47, it is allowed to return these nodes as the result of the path expression, without searching for another product node that would raise an error because it has an id child whose value is not an integer.
//product[id = 47]
For a variety of reasons, including optimization, implementations may rewrite expressions into a different form. There are a number of rules that limit the extent of this freedom:
Other than the raising or not raising of errors, the result of evaluating a rewritten expression must conform to the semantics defined in this specification for the original expression.
Note:
This allows an implementation to return a result in cases where the original expression would have raised an error, or to raise an error in cases where the original expression would have returned a result. The main cases where this is likely to arise in practice are (a) where a rewrite changes the order of evaluation, such that a subexpression causing an error is evaluated when the expression is written one way and is not evaluated when the expression is written a different way, and (b) where intermediate results of the evaluation cause overflow or other out-of-range conditions.
Note:
This rule does not mean that the result of the expression will always be the same in non-error cases as if it had not been rewritten, because there are many cases where the result of an expression is to some degree implementation-dependent or implementation-defined.
The rules described in 2.5.5 Guarded Expressions ensure that for certain kinds of expression (for example conditional expressions), changing the order of evaluation of subexpressions does not result in dynamic errors that would not otherwise occur.
Expressions must not be rewritten in such a way as to create or remove static errors. The static errors in this specification are defined for the original expression, and must be preserved if the expression is rewritten.
As stated earlier, an expression must not be rewritten to dispense with a required cardinality check: for example, string-length(//title) must raise an error if the document contains more than one title element.
Changes in 4.0 (next | previous)
The rules for “errors and optimization” have been tightened up to disallow many cases of optimizations that alter error behavior. In particular there are restrictions on reordering the operands of and and or, and of predicates in filter expressions, in a way that might allow the processor to raise dynamic errors that the author intended to prevent. [Issue 71 PR 230 15 November 2022]
[Definition: An expression E is said to be guarded by some governing condition C if evaluation of E is not allowed to fail with a dynamic error except when C applies.]
For example, in a conditional expression if (P) then T else F, the subexpression T is guarded by P, and the subexpression F is guarded by not(P). One way an implementation can satisfy this rule is by not evaluating T unless P is true, and likewise not evaluating F unless P is false. Another way of satisfying the rule is for the implementation to evaluate all the subexpressions, but to catch any errors that occur in a guarded subexpression so they are not propagated.
The existence of this rule enables errors to be prevented by writing expressions such as if ($y eq 0) then "N/A" else ($x div $y). This example will never fail with a divide-by-zero error because the else branch of the conditional is guarded.
Similarly, in the mapping expression E1!E2, the subexpression E2 is guarded by the existence of an item from E1. This means, for example, that the expression (1 to $n)!doc('bad.xml') must not raise a dynamic error if $n is zero. The rule governing evaluation of guarded expressions is phrased so as not to disallow “loop-lifting” or “constant-folding” optimizations whose aim is to avoid repeated evaluation of a common subexpression; but such optimizations must not result in errors that would not otherwise occur.
The complete list of expressions that have guarded subexpressions is as follows:
In a conditional expression (IfExpr) the then branch is guarded by the condition being true, and the else branch is guarded by the condition being false.
In a switch expression (SwitchExpr), the return expression of a particular case is guarded by the condition for that case matching, and no earlier case matching.
In a typeswitch expression (TypeswitchExpr), the return expression of a particular case is guarded by the condition for that case matching, and no earlier case matching.
In an and expression, the second operand is guarded by the value of the first operand being true.
In an or expression, the second operand is guarded by the value of the first operand being false.
In an otherwise expression (OtherwiseExpr), the second operand is guarded by the value of the first operand being anthe empty sequence.
In a path expression of the form E1/E2 or E1//E2, and in a mapping expression of the form E1!E2, the right-hand operand E2 is guarded by the existence of at least one item in the result of evaluating E1.
This rule applies even if E2 does not reference the context value. For example, no dynamic error can be thrown by the expression (1 to $n)!doc('bad.xml') in the case where $n is zero.
In a filter expression of the form E[P], the predicate P is guarded by the existence of at least one item in the result of evaluating E.
This rule has the consequence that in a filter expression with multiple predicates, such as E[P1][P2], evaluation of P2 must not raise a dynamic error unless P1 returns true. This rule does not prevent reordering of predicates (for example, to take advantage of indexes), but it does require that any such reordering must not result in errors that would not otherwise occur.
In a FLWOR expression (FLWORExpr), an expression that is logically dependent on the tuples in the tuple stream is guarded by the existence of a relevant tuple. This applies even where the expression does not actually reference any of the variable bindings in the tuple stream. For example, in the expression for $x in S return E, the expression E is guarded by the existence of an item bound to $x.
This means that the expression for $x in 1 to $n return doc('bad.xml') must not raise a dynamic error in the case where $n is zero.
In a quantified expression (QuantifiedExpr) such as some $x in S satisfies P, the expression P is guarded by the existence of an item bound to $x.
The fact that an expression is guarded does not remove the obligation to report static errors in the expression; nor does it remove the option to report statically detectable type errors.
Note:
These rules do not constrain the order of evaluation of subexpressions. For example, given an expression such as //person[@first = "Winston"][@last = "Churchill"], or equivalently //person[@first = "Winston" and @last = "Churchill"], an implementation might use an index on the value of @last to select items that satisfy the second condition, and then filter these items on the value of the first condition. Alternatively, it might evaluate both predicates in parallel. Or it might interpose an additional redundant condition: //person[string-length(@first) + string-length(@last) = 16][@first = "Winston"][@last = "Churchill"]. But implementations must ensure that such rewrites do not result in dynamic errors being reported that would not occur if the predicates were evaluated in order as written.
Note:
Although the rules for guarded expressions prevent optimizations resulting in spurious errors, they do not prevent optimizations whose effect is to mask errors. For example, the rules guarantee that ("A", 3)[. instance of xs:integer][. eq 3] will not raise an error caused by the comparison ("A" eq 3), but they do not guarantee the converse: the expression ("A", 3)[. eq 3][. instance of xs:integer] may or may not raise a dynamic error.
Note:
The rules in this section do not disallow all expression rewrites that might result in dynamic errors. For example, rewriting ($x - $y + $z) as ($x + $z - $y) is permitted even though it might result in an arithmetic overflow.
Note:
Some implementations allow calls on external functions that have side-effects. The semantics of such function calls are entirely implementation defined. Processors may choose to reference the rules for guarded expressions when defining the behavior of such function calls, but this is outside the scope of the language specification.
Changes in 4.0 (next | previous)
The rules for reporting type errors during static analysis have been changed so that a processor has more freedom to report errors in respect of constructs that are evidently wrong, such as @price/@value, even though dynamic evaluation is defined to return anthe empty sequence rather than an error. [Issue 602 PR 603 25 July 2023]
[Definition: Certain expressions, while not erroneous, are classified as being implausible, because they achieve no useful effect.]
An example of an implausible expression is @code/text(). This expression will always evaluate to anthe empty sequence, because attribute nodes cannot have text node children. The semantics of the expression are well defined, but it is likely that the user writing this expression intended something different: if they wanted to write an expression that evaluated to anthe empty sequence, there would be easier ways to write it.
Where an expression is classified (by rules in this specification) as being implausible, a processor may (but is not required to) raise a static error.
For reasons of backwards compatibility and interoperability, and to facilitate automatic generation of XQuery 4.0 code, a processor must provide a mode of operation in which implausible expressions are not treated as static errors, but are evaluated with the defined semantics for the expression.
Some other examples of implausible expressions include:
round(tokenize($input)). The result of fn:tokenize is a sequence of strings (xs:string*), while the required type for the first argument of fn:round is optional numeric (xs:numeric?). The expression can succeed only in the exceptional case where the result of fn:tokenize is anthe empty sequence, in which case the result of fn:round will also be anthe empty sequence; it is therefore highly likely that the expression was written in error.
parse-csv($input)?column-names. The signature of the parse-csv function declares its return type as record(columns, rows). There is no field in this record named column-names, and therefore the lookup expression will always return anthe empty sequence. Again, there is no good reason that a user would write this, so it is likely that it was written in error.
Note:
The specification is deliberately conservative in the choice of constructs that have been classified as implausible. Constructs have not been classified as implausible merely because there are better ways of writing the same thing, but only in cases where it is considered that no user in full understanding of the specification would intentionally write such a construct. All these cases correspond to situations that would be classed as errors in a language with stricter static typing rules.
Note:
In many cases the classification of constructs as implausible is designed to protect users from usability problems that have been found with earlier versions of the language. without introducing backwards incompatibilities.
This section explains some concepts that are important to the processing of XQuery 4.0 expressions.
An ordering called document order is defined among all the nodes accessible during processing of a given query , which may consist of one or more trees (documents or fragments).
Document order applies both to XNodes (typically corresponding to nodes in an XML document, and generally referred to simply as nodes), and also to JNodesDM, often corresponding to the contents of a JSON source text. These are known collectively as GNodes (for "generalized node").
Document order is defined in [XDM 4.0] section 6.2 Document Order, and its definition is repeated here for convenience. Document order is a total ordering, although the relative order of some nodes is implementation-dependent. [Definition: Informally, document order is the order in which nodes appear in the XML serialization of a document.] [Definition: Document order is stable, which means that the relative order of two nodes will not change during the processing of a given query , even if this order is implementation-dependent.] [Definition: The node ordering that is the reverse of document order is called reverse document order.]
Within an XTreeDM, (that is, a tree consisting of XNodes), document order satisfies the following constraints:
The root node precedes all other nodes.
A parent node precedes its children (and therefore its descendants).
The children of a node N precede the following siblings of N.
Attribute nodes immediately follow the namespace nodes of the element node with which they are associated. The relative order of attribute nodes is stable but implementation-dependent.
The relative order of siblings is the order in which they occur in the children property of their parent node.
Similarly, within an JTreeDM, (that is, a tree consisting of JNodes), document order satisfies the following constraints:
The root JNode precedes all other JNodes.
A parent JNode precedes its children (and therefore its descendants).
The children of a JNode N precede the following siblings of N.
The children of a JNode that wraps an array follow the ordering of the members of the array.
The children of a JNode that wraps a map follow the ordering of the entries in the map.
The relative order of nodes in distinct trees is stable but implementation-dependent, subject to the following constraint: If any node in a given tree T1 is before any node in a different tree T2, then all nodes in tree T1 are before all nodes in tree T2.
Under certain circumstances (some of which are listed below), it is necessary to find the effective boolean value of a value. [Definition: The effective boolean value of a value is defined as the result of applying the fn:boolean function to the value.]
The dynamic semantics of fn:boolean are repeated here for convenience:
If its operand is anthe empty sequence, fn:boolean returns false.
If its operand is a sequence whose first item is a GNode, fn:boolean returns true.
If its operand is a singleton value of type xs:boolean or derived from xs:boolean, fn:boolean returns the value of its operand unchanged.
If its operand is a singleton value of type xs:string, xs:anyURI, xs:untypedAtomic, or a type derived from one of these, fn:boolean returns false if the operand value has zero length; otherwise it returns true.
If its operand is a singleton value of any numeric type or derived from a numeric type, fn:boolean returns false if the operand value is NaN or is numerically equal to zero; otherwise it returns true.
In all other cases, fn:boolean raises a type error [err:FORG0006]FO40.
Note:
For instance, fn:boolean raises a type error if the operand is a function, a map, or an array.
The effective boolean value of a sequence is computed implicitly during processing of the following types of expressions:
Logical expressions (and, or)
The fn:not function
The where clause of a FLWOR expression
Certain types of predicates, such as a[b]
Conditional expressions (if)
Quantified expressions (some, every)
WindowStartCondition and WindowEndCondition in window clauses.
Note:
The definition of effective boolean value is not used when casting a value to the type xs:boolean, for example in a cast expression. It also plays no role in the coercion rules used when passing a value to a function whose signature declares a parameter of type xs:boolean.
As noted in 2.1.3 Values, every value in XQuery 4.0 is regarded as a sequence of zero, one, or more items. The type system of XQuery 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 XQuery 4.0 is related to the type system of [XML Schema 1.0] or [XML Schema 1.1] in two ways:
atomic items in XQuery 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 XQuery 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.
[Definition: A sequence type is a type that can be expressed using the SequenceType syntax. Sequence types are used whenever it is necessary to refer to a type in an XQuery 4.0 expression. Since all values are sequences, every value matches one or more sequence types.]
Whenever it is necessary to refer to a sequence type in an XQuery 4.0 expression, the SequenceType syntax is used.
SequenceType | ::= | ("empty-sequence" "(" ")") |
ItemType | ::= | RegularItemType | FunctionType | TypeName | ChoiceItemType |
OccurrenceIndicator | ::= | "?" | "*" | "+" |
| /* xgc: occurrence-indicators */ |
[Definition: A sequence type designator is a syntactic construct conforming to the grammar rule SequenceType. A sequence type designator is said to designate a sequence type.]
With the exception of the special type empty-sequence(), a sequence type consists of an item type that constrains the type of each item in the sequence, and a cardinality that constrains the number of items in the sequence. Apart from the item type item(), which permits any kind of item, item types divide into node types (such as element()), generalized atomic types (such as xs:integer) and function types (such as function() as item()*).
The cardinality of a sequence type is represented in the sequence type designator syntax by an OccurrenceIndicator. The occurrence indicators +, *, and ? bind to the last ItemType in the SequenceType, as described in the occurrence-indicators constraint.
[Definition: SequenceType matching compares a value with an expected sequence type. ] For example, an instance of expression returns true if a given value matches a given sequence type, and false if it does not.
An XQuery 4.0 implementation must be able to determine relationships among the types in type annotations in an XDM instance and the types in the in-scope schema definitions (ISSD). An XQuery 4.0 implementation must be able to determine relationships among the types in ISSDs used in different modules of the same query.
[Definition: The use of a value that has a dynamic type that is a subtype of the expected type is known as subtype substitution.] Subtype substitution does not change the actual type of a value. For example, if an xs:integer value is used where an xs:decimal value is expected, the value retains its type as xs:integer.
The rules for SequenceType matching are given below, with examples (the examples are for purposes of illustration, and do not cover all possible cases).
The sequence typeempty-sequence() matches a value that is the empty sequence.
An ItemType with no OccurrenceIndicator matches any value that contains exactly one item if the ItemType matches that item (see 3.2 Item Types).
An ItemType with an OccurrenceIndicator matches a value if the number of items in the value matches the OccurrenceIndicator and the ItemType matches each of the items in the value.
An OccurrenceIndicator specifies the number of items in a sequence, as follows:
? matches zero or one items
* matches zero or more items
+ matches one or more items
As a consequence of these rules, any sequence type whose OccurrenceIndicator is * or ? matches a value that is anthe empty sequence.
[Definition: An item type is a type that can be expressed using the ItemType syntax, which forms part of the SequenceType syntax. Item types match individual items.]
Note:
While this definition is adequate for the purpose of defining the syntax of XQuery 4.0, it ignores the fact that there are also item types that cannot be expressed using XQuery 4.0 syntax: specifically, item types that reference an anonymous simple type or complex type defined in a schema. Such types can appear as type annotations on nodes following schema validation.
In most cases, the set of items matched by an item type consists either exclusively of atomic items, exclusively of nodes, or exclusively of function itemsDM. Exceptions include the generic types item(), which matches all items, xs:error, which matches no items, and choice item types, which can match any combination of types.
[Definition: An item type designator is a syntactic construct conforming to the grammar rule ItemType. An item type designator is said to designate an item type.]
Note:
Two item type designators may designate the same item type. For example, element() and element(*) are equivalent, as are attribute(A) and attribute(A, xs:anySimpleType).
Lexical QNames appearing in an item type designator(other than within a function assertion) are expanded using the default type namespace rule. Equality of QNames is defined by the eq operator.
This section defines the syntax and semantics of different ItemTypes in terms of the values that they match.
Note:
For an explanation of the EBNF grammar notation (and in particular, the operators ++ and **), see A.1 EBNF.
An item type designator written simply as an EQName (that is, a TypeName) is interpreted as follows:
If the name is written as a lexical QName, then it is expanded using the default type namespace rule.
If the expanded name matches a named item type in the static context, then it is taken as a reference to the corresponding item type. The rules that apply are the rules for the expanded item type definition.
Otherwise, it must match the name of a type in the in-scope schema types in the static context: specifically, an atomic type or a pure union type. See 3.5 Schema Types for details.
Note:
A name in the xs namespace will always fall into this category, since the namespace is reserved. See 2.1.4 Namespaces and QNames.
If the name cannot be resolved to a type, a static error is raised [err:XPST0051].
The following sections describe the syntax for item types for functions, including arrays and maps.
The subtype relation among these types is described in the various subsections of 3.3.2 Subtypes of Item Types.
A MapType designates an item type that either matches any map, or that matches maps whose keys and values are constrained to specific types.
MapType | ::= | AnyMapType | TypedMapType |
AnyMapType | ::= | "map" "(" "*" ")" |
TypedMapType | ::= | "map" "(" ItemType "," SequenceType ")" |
ItemType | ::= | RegularItemType | FunctionType | TypeName | ChoiceItemType |
SequenceType | ::= | ("empty-sequence" "(" ")") |
An AnyMapTypemap(*) matches any map.
The MapTypemap(K, V) matches any map where every key is an instance of K and every value is an instance of V.
The entry-orderDM of a map has no effect on whether the map matches a particular map type.
Although the grammar for TypedMapType allows the key to be described using the full ItemType syntax, the item type used must be a generalized atomic type [err:XPST0152].
For example, given a map $M whose keys are integers and whose results are strings, such as { 0: "no", 1: "yes" }, the following following expressions deliver the result shown:
$M instance of map(*) returns true
$M instance of map(xs:integer, xs:string) returns true
$M instance of map(xs:decimal, xs:anyAtomicType) returns true
$M instance of map(xs:int, xs:string) returns false
$M instance of map(xs:integer, xs:token)) returns false
A map is also a function item, and therefore matches certain function types. Specifically, a map that matches map(K, V) also matches a function type of the form function(xs:anyAtomicType) as R provided that both the following conditions are satisfied:
Note:
To understand this rule, consider the use of a map $M in a function call $M($K), which is equivalent to the function call map:get($M, $K). This function accepts any atomic item for the argument $K, and hence matches a function type that requires an argument type of xs:anyAtomicType. If the key $K is present in the map, the result of the function will be a value of type V; if not, it will be anthe empty sequence. The map is therefore substitutable for the function type provided that the function type allows both a value of type V and the empty sequence as possible results.
The key type K does not enter into this rule. That is because in the function call $M($K), the sought key $K does not have to be of the same type as the keys actually present in the map.
The transitivity rules for item type matching mean that if an item M matches a type T, and T is a subtype of U, then M also matches type U. So the fact that a map from integers to strings (map(xs:integer, xs:string)) matches function(xs:anyAtomicType) as xs:string? means that it will also match other function types such as function(xs:integer) as xs:string? and function(xs:decimal) as xs:anyAtomicType?
Furthermore, the rules for function coercion mean that any map can be supplied as a value in a context where it does not actually match the required function type, but can be coerced to a function that does. For example a map of type map(xs:integer, xs:string) can be coerced to a function of type function(xs:integer) as xs:string; in this situation a type error will occur only if a call on the function actually returns anthe empty sequence.
Examples:
$M instance of fn(*) returns true
$M instance of fn(xs:anyAtomicType) as item()* returns true
$M instance of fn(xs:integer) as item()* returns true
$M instance of fn(xs:int) as item()* returns true
$M instance of fn(xs:string) as item()* returns true
not($M instance of fn(xs:integer) as xs:string) returns true
Note:
The last case might seem surprising; however, function coercion ensures that $M can be used successfully anywhere that the required type is fn(xs:integer) as xs:string.
Rules defining whether one map type is a subtype of another are given in 3.3.2.7 Subtyping Maps.
A RecordType matches maps that meet specific criteria.
For example, the RecordTyperecord(r as xs:double, i as xs:double) matches a map if the map has exactly two entries: an entry with key "r" whose value is a singletonxs:double value, and an entry with key "i" whose value is also a singletonxs:double value.
Record types describe a subset of the value space of maps. They do not define any new kinds of values, or any additional operations. They are useful in many cases to describe more accurately the type of a variable, function parameter, or function result, giving benefits both in the readability of the code, and in the ability of the processor to detect and diagnose type errors and to optimize execution.
RecordType | ::= | AnyRecordType | TypedRecordType |
AnyRecordType | ::= | "record" "(" "*" ")" |
TypedRecordType | ::= | "record" "(" (FieldDeclaration ** ",") ExtensibleFlag? ")" |
FieldDeclaration | ::= | FieldName "?"? ("as" SequenceType)? |
FieldName | ::= | NCName | StringLiteral |
StringLiteral | ::= | AposStringLiteral | QuotStringLiteral |
| /* ws: explicit */ | ||
SequenceType | ::= | ("empty-sequence" "(" ")") |
ExtensibleFlag | ::= | "," "*" |
If the list of fields ends with ",*" then the record type is said to be extensible. For example, the RecordTyperecord(e as element(Employee), *) matches a map if it has an entry with key "e" whose value matches element(Employee), regardless what other entries the map might contain.
For generality:
The syntax record() defines a record type that has no explicit fields and that is not extensible. The only thing it matches is an empty mapDM.
The syntax record(*) defines an extensible record type that has no explicit field declarations. It is equivalent to the item type map(*): that is, it matches any map.
A record type can constrain only those entries whose keys are strings, but when the record type is marked as extensible, then other entries may be present in the map with either string or non-string keys. Entries whose key is a string can be expressed using an (unquoted) NCName if the key conforms to NCName syntax, or using a (quoted) string literal otherwise.
Although constructors for named record types produce a map in which the entry orderDM reflects the order of field definitions in the record type definition, the entry orderDM of a map has no effect on whether the map matches a particular record type: the entries in a map do not have to be in any particular order.
Note:
Lookup expressions have been extended in 4.0 so that non-NCName keys can be used without parentheses: employee?"middle name"
If the type declaration for a field is omitted, then item()* is assumed: that is, the map entry may have any type.
If the field name is followed by a question mark, then the value must have the specified type if it is present, but it may also be absent. For example, the RecordTyperecord(first as xs:string, middle? as xs:string, last as xs:string, *) requires the map to have string-valued entries with keys "first" and "last"; it also declares that if the map has an entry with key "middle", the value of that entry must be a single xs:string. Declaring the type as record(first as xs:string, middle? as xs:string?, last as xs:string, *) also allows the entry with key "middle" to be present but empty.
Note:
Within an extensible record type, a FieldDeclaration that is marked optional and has no declared type does not constrain the map in any way, so it serves no practical purpose, but it is permitted because it may have documentary value.
The names of the fields in a record type must be distinct [err:XPST0021].
If a variable $rec is known to conform to a particular record type, then when a lookup expression $rec?field is used, (a) the processor can report a type error if $rec cannot contain an entry with name field (see 4.14.3.4 Implausible Lookup Expressions), and (b) the processor can make static type inferences about the type of value returned by $rec?field.
Note:
(TODO: change function signatures as suggested here!) A number of functions in the standard function library use maps as function arguments; this is a useful technique where the information to be supplied across the interface is highly variable. However, the type signature for such functions typically declares the argument type as map(*), which gives very little information (and places very few constraints) on the values that are actually passed across. Using record types offers the possibility of improving this: for example, the options argument of fn:parse-json, previously given as map(*), can now be expressed as record(liberal? as xs:boolean, duplicates? as xs:string, escape? as xs:boolean, fallback as fn(xs:string) as xs:string, *). In principle the xs:string type used to describe the duplicates option could also be replaced by a schema-defined subtype of xs:string that enumerates the permitted values ("reject", "use-first", "use-last").
The use of a record type in the signature of such a function causes the coercion rules to be invoked. So, for example, if the function expects an entry in the map to be an xs:double value, it becomes possible to supply a map in which the corresponding entry has type xs:integer.
Greater precision in defining the types of such arguments also enables better type checking, better diagnostics, better optimization, better documentation, and better syntax-directed editing tools.
Note:
One of the motivations for introducing record types is to enable better pattern matching in XSLT when processing JSON input. With XML input, patterns are often based around XML element names. JSON has no direct equivalent of XML’s element names; matching a JSON object such as {longitude: 130.2, latitude: 53.4} relies instead on recognizing the property names appearing in the object. XSLT 4.0, by integrating record types into pattern matching syntax, allows such an object to be matched with a pattern of the form match="record(longitude, latitude)"
Rules defining whether one record type is a subtype of another are given in 3.3.2.9 Subtyping Records.
[Definition: Given two sequence types or item types, the rules in this section determine if one is a subtype of the other. If a type A is a subtype of type B, it follows that every value matched by A is also matched by B.]
Note:
The relationship subtype(A, A) is always true: every type is a subtype of itself.
Note:
The converse is not necessarily true: we cannot infer that if every value matched by A is also matched by B, then A is a subtype of type B. For example, A might be defined as the set of strings matching the regular expression [A-Z]*, while B is the set of strings matching the regular expression [A-Za-z]*; no subtype relationship holds between these types.
The rules for deciding whether one sequence type is a subtype of another are given in 3.3.1 Subtypes of Sequence Types. The rules for deciding whether one item type is a subtype of another are given in 3.3.2 Subtypes of Item Types.
Note:
The subtype relationship is not acyclic. There are cases where subtype(A, B) and subtype(B, A) are both true. This implies that A and B have the same value space, but they can still be different types. For example this applies when A is a union type with member types xs:string and xs:integer, while B is a union type with member types xs:integer and xs:string. These are different types ("23" cast as A produces a string, while "23" cast as B produces an integer, because casting is attempted to each member type in order) but both types have the same value space.
We use the notation A ⊆ B, or itemtype-subtype(A, B) to indicate that an item typeA is a subtype of an item type B. This section defines the rules for deciding whether any two item types have this relationship.
The rules in this section apply to item types, not to item type designators. For example, if the name STR has been defined in the static context as a named item type referring to the type xs:string, then anything said here about the type xs:string applies equally whether it is designated as xs:string or as STR, or indeed as the parenthesized forms (xs:string) or (STR).
References to named item types are handled as described in 3.3.2.10 Subtyping of Named Item Types.
The relationship A ⊆ B is true if and only if at least one of the conditions listed in the following subsections applies:
Given item types A and B, A ⊆ B is true if any of the following apply:
Both of the following are true:
A is map(K, V), for any K and V
B is map(*)
All the following are true:
A is map(Ka, Va)
B is map(Kb, Vb)
Ka ⊆ Kb
Va ⊑ Vb
Both the following are true:
A is map(*) (or, because of the transitivity rules, any other map type)
B is function(*)
Both the following are true:
A is map(*) (or, because of the transitivity rules, any other map type)
B is function(xs:anyAtomicType) as item()*
All the following are true:
A is map(K, V)
B is function(xs:anyAtomicType) as R
V ⊆ R
empty-sequence() ⊆ R
map(xs:int, node()) ⊆ function(xs:anyAtomicType) as node()?
map(xs:int, node()+) ⊆ function(xs:anyAtomicType) as node()*
The function accepts type xs:anyAtomicType rather than xs:int, because $M("xyz") is a valid call on a map (treated as a function) even when all the keys in the map are integers.
The return type of the function is extended from node() or node()+ to allow anthe empty sequence because $M("xyz") can return anthe empty sequence even if none of the entries in the map contains anthe empty sequence.
Changes in 4.0 (next | previous)
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 anthe 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:
Each item in V is processed against the required item type R using the item coercion rules defined in 3.4.1 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 atomized 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 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.3 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:
AnThe 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.5.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.
An expression is deemed to be implausible [err:XPTY0006] if the static type of the expression, after applying all necessary coercions, is substantively disjoint with the required type T.
[Definition: Two sequence types are deemed to be substantively disjoint if (a) neither is a subtype of the other (see 3.3.1 Subtypes of Sequence Types) and (b) the only values that are instances of both types are one or more of the following:
The empty sequence, ().
The empty mapDM, {}.
The empty arrayDM, [].
]
Note:
Examples of pairs of sequence types that are substantively disjoint include:
xs:integer* and xs:string*
map(xs:integer, node()) and map(xs:string, node())
array(xs:integer) and array(xs:string)
For example, supplying a value whose static type is xs:integer* when the required type is xs:string* is implausible, because it can succeed only in the special case where the actual value supplied is anthe empty sequence.
Note:
The case where the supplied type and the required type are completely disjoint (for example map(*) and array(*)) is covered by the general rules for type errors: that case can always be reported as a static error.
Examples of implausible coercions include the following:
round(timezone-from-time($now)). The result of fn:timezone-from-time is of type xs:dayTimeDuration?, which is substantively disjoint with the required type of fn:round, namely xs:numeric?.
function($x as xs:integer) as array(xs:string) { array { 1 to $x } }. The type of the function body is array(xs:integer), which is substantively disjoint with the required type array(xs:string): the function can succeed only in the exceptional case where the function body delivers an empty arrayDM.
Changes in 4.0 (next | previous)
Function coercion now allows a function with arity N to be supplied where a function of arity greater than N is expected. For example this allows the function true#0 to be supplied where a predicate function is required.
It has been clarified that function coercion applies even when the supplied function item matches the required function type. This is to ensure that arguments supplied when calling the function are checked against the signature of the required function type, which might be stricter than the signature of the supplied function item. [Issue 1020 PRs 1023 1128 9 April 2024]
Function coercion is a transformation applied to function items during application of the coercion rules. [Definition: Function coercion wraps a function item in a new function whose signature is the same as the expected type. This effectively delays the checking of the argument and return types until the function is called.]
Given a function F, and an expected function type T, function coercion proceeds as follows:
If F has higher arity than T, a type error is raised [err:XPTY0004]
If F has lower arity than T, then F is wrapped in a new function that declares and ignores the additional argument; the following steps are then applied to this new function.
For example, if T is function(node(), xs:boolean) as xs:string, and the supplied function is fn:name#1, then the supplied function is effectively replaced by function($n as node(), $b as xs:boolean) as xs:string { fn:name($n) }
Note:
This mechanism makes it easier to design versatile and extensible higher-order functions. For example, in previous versions of this specification, the second argument of the fn:filter function expected an argument of type function(item()) as xs:boolean. This has now been extended to function(item(), xs:integer) as xs:boolean, but existing code continues to work, because callback functions that are not interested in the value of the second argument simply ignore it.
A type error is raised [err:XPTY0004] if, for any parameter type, or for the result type, the relevant type in the signature of the supplied function and the relevant type in the expected function type are substantively disjoint.
For example, the types xs:integer and xs:string are substantively disjoint, so a function with signature function(xs:integer) as xs:boolean cannot be supplied where the expected type is function(xs:string) as xs:boolean.
Function coercion then returns a new function item with the following properties (as defined in [XDM 4.0] section 8.1 Function Items):
name: The name of F(if not absent).
identity: A new function identity distinct from the identity of any other function item.
Note:
See also 4.5.7 Function Identity.
signature: Annotations is set to the annotations of F. TypedFunctionType is set to the expected type.
implementation: In effect, a FunctionBody that calls F, passing it the parameters of this new function, in order.
nonlocal variable bindings: An empty mapping.
These rules have the following consequences:
SequenceType matching of the function’s arguments and result are delayed until that function is called.
When the coerced function is called, the supplied arguments must match the parameter typed defined in T; it is not sufficient to match the parameter types defined in F.
The coercion rules rules applied to the function’s arguments and result are defined by the SequenceType it has most recently been coerced to. Additional coercion rules could apply when the wrapped function is called.
If an implementation has static type information about a function, that can be used to type check the function’s argument and return types during static analysis.
When function coercion is applied to a map or an array, the resulting function is not a map or array, and cannot be used as such. For example, the expression
let $f as function(xs:integer) as xs:boolean := { 0: false(), 1: true() }
return $f?0raises a type error, because a lookup expression requires the left hand operand to be a map or array, and $f is neither.
When function types are used as alternatives in a choice item type, the supplied function is coerced to the first alternative for which coercion does not raise a type error. In this situation it is important to write the alternatives in order, with the most specific first.
For instance, consider the following query:
declare function local:filter(
$s as item()*,
$p as function(xs:string) as xs:boolean
) as item()* {
$s[$p(.)]
};
let $f := function($a) { starts-with($a, "E") }
return local:filter(("Ethel", "Enid", "Gertrude"), $f) The function $f has a static type of function(item()*) as item()*. When the local:filter() function is called, the following occurs to the function:
The coercion rules result in applying function coercion to $f, wrapping $f in a new function ($p) with the signature function(xs:string) as xs:boolean.
$p is matched against the SequenceType of function(xs:string) as xs:boolean, and succeeds.
When $p is called inside the predicate, coercion and SequenceType matching rules are applied to the context value argument, resulting in an xs:string value or a type error.
$f is called with the xs:string, which returns an xs:boolean.
$p applies coercion rules to the result sequence from $f, which already matches its declared return type of xs:boolean.
The xs:boolean is returned as the result of $p.
Note:
The semantics of function coercion are specified in terms of wrapping the functions. Static typing may be able to reduce the number of places where this is actually necessary. However, it cannot be assumed that because a supplied function is an instance of the required function type, no function coercion is necessary: the supplied function might not perform all required checks on the types of its arguments.
Since maps and arrays are also functions in XQuery 4.0, function coercion applies to them as well. For instance, consider the following expression:
let $m := {
"Monday" : true(),
"Wednesday" : false(),
"Friday" : true()
}
let $days := ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday")
return filter($days, $m) The map $m is an instance of function(xs:anyAtomicType?) as item()*. When the fn:filter() function is called, the following occurs to the map:
The map $m is treated as a function equivalent to map:get($m, ?).
The coercion rules result in applying function coercion to this function, wrapping it in a new function (M′) with the signature function(item(), xs:integer) as xs:boolean.
When M′ is called by fn:filter(), coercion and SequenceType matching rules are applied to the argument, resulting in an item() value ($a) or a type error.
The function map:get($m, ?) is called with $a as the argument; this returns either an xs:boolean or the empty sequence (call the result R).
The wrapper function $p applies the coercion rules to R. If R is an xs:boolean the matching succeeds. When it is anthe empty sequence (in particular, $m does not contain a key for "Tuesday"), a type error is raised [err:XPTY0004], since the expected type is xs:boolean and the actual type is an, which does not allow the empty sequence.
Consider the following expression:
let $m := {
"Monday" : true(),
"Wednesday" : false(),
"Friday" : true(),
}
let $days := ("Monday", "Wednesday", "Friday")
return filter($days, $m)In this case the result of the expression is the sequence ("Monday", "Friday"). But if the input sequence included the string "Tuesday", the filter operation would fail with a type error.
Note:
Function coercion applies even if the supplied function matches the required type.
For example, consider this case:
declare function local:filter(
$s as item()*,
$p as function(xs:string) as xs:boolean
) as item()* {
$s[$p(.)]
};
let $f := function($a) { $a mod 2 = 0 }
return local:filter(1 to 10, $f)Here the supplied function $f is an instance of the required type, because its signature defaults the argument type to item()*, which is a supertype of xs:string. The expression $s[$p(.)] could in principle succeed. However, function coercion ensures that the supplied function is wrapped in a function that requires the argument to be of type xs:string, so the call fails with a type error when the wrapping function is invoked supplying an xs:integer as the argument.
This has the consequence that in XQuery 4.0, there is a backwards incompatibility introduced because coercion rules now apply to global variable declarations (declare variable) and local variable bindings (for example let clauses). Previously the following would execute without error:
let $f as function(xs:integer) as item()* := function($x) { $x + 1 }
return $f(12.3)With XQuery 4.0, as a consequence of function coercion, this fails with a type error because the argument supplied in the function call is not of type xs:integer.
This section illustrates the effect of the coercion rules with examples.
Consider the case where the required type (of a variable, or a function argument) is xs:string. For example, the second argument of fn:matches, which expects a regular expression. The table below illustrates the values that might be supplied, and the coercions that are applied.
| Supplied Value | Coercion |
|---|---|
"[0-9]" | None; the supplied value is an instance of the required type. |
default-language() | None; the supplied value is an instance of |
<a>[0-9]</a> | The supplied element node is atomized. Unless it has been schema-validated, the typed value will be an instance of Supplying an element whose type annotation is (say) |
xs:anyURI("urn:dummy") | Supplying an instance of |
["a|b"] | Supplying an array holding a single string succeeds, because the rules cause the array to be atomized, and the value after atomization is a single string. Supplying an array holding multiple strings would fail. |
Consider the case where the required type (of a variable, or a function argument) is xs:decimal?. For example, the first argument of fn:seconds, which expects a decimal number of seconds. The table below illustrates the values that might be supplied, and the coercions that are applied.
| Supplied Value | Coercion |
|---|---|
12.4 | None; the supplied value is an instance of the required type. |
() | None; anthe empty sequence is an instance of the required type. |
42 | None; the supplied value is an instance of |
math:pi() | The supplied value is an instance of |
("a", "b")[.="c"] | The supplied value is anthe empty sequence, which is a valid instance of the required type |
(1.5, 2.5, 3.5) | A type error is raised. |
<a>3.14159</a> | The element node is atomized; unless it has been schema-validated, the result will be |
[1.5] | The array is atomized, and the result is a valid instance of the required type |
[] | The array is atomized, and the result is anthe empty sequence, which is a valid instance of the required type |
Consider the case where the required type (of a variable, or a function argument) is xs:positive-integer. The table below illustrates the values that might be supplied, and the coercions that are applied.
| Supplied Value | Coercion |
|---|---|
12 | The supplied value is of type |
12.1 | This fails with a type error, because the |
math:pi() | This fails with a type error. A value of type |
<a>1200</a> | The supplied element node is atomized. If the element has not been schema-validated, the result will be an |
Consider the first parameter of the function fn:char, whose declared type is (xs:string | xs:positiveInteger). The rules are the same as if it were a union typed declared in an imported schema.
| Supplied Value | Coercion |
|---|---|
"amp" | The supplied value is of type |
"#" | The supplied value is of type |
0x25 | The supplied value is of type |
<a>0x25</a> | The supplied element node is atomized. Assuming that the node has not been schema-validated, the result is an instance of |
Suppose the required type is (record(x as xs:decimal, y as xs:decimal, *) | record(size as enum("S", "M", "L", "XL"), *)).
| Supplied Value | Coercion |
|---|---|
{ "x": 1, "y": 2, "z": 3 } | The supplied value is an instance of the first record type: no coercion is necessary. |
{ "size": "M" } | The supplied value is an instance of the second record type: no coercion is necessary. |
{ "x": 1, "y": 2, "size": "XL" } | The supplied value is an instance of both record types: no coercion is necessary. |
{ "x": 1e0, "y": 2e0, "size": "XL" } | The supplied value is not an instance of the first record type because the fields are of type |
{ "x": 1e0, "y": 2e0, "size": "XXL" } | The supplied value is not an instance of the first record type because the fields are of type |
This section discusses each of the basic kinds of expression. Each kind of expression has a name such as PathExpr, which is introduced on the left side of the grammar production that defines the expression. Since XQuery 4.0 is a composable language, each kind of expression is defined in terms of other expressions whose operators have a higher precedence. In this way, the precedence of operators is represented explicitly in the grammar.
The order in which expressions are discussed in this document does not reflect the order of operator precedence. In general, this document introduces the simplest kinds of expressions first, followed by more complex expressions. For the complete grammar, see Appendix [A XQuery 4.0 Grammar].
[Definition: A query consists of one or more modules.] If a query is executable, one of its modules has a Query Body containing an expression whose value is the result of the query. An expression is represented in the XQuery grammar by the symbol Expr.
Expr | ::= | (ExprSingle ++ ",") |
ExprSingle | ::= | FLWORExpr |
ExprSingle | ::= | FLWORExpr |
FLWORExpr | ::= | InitialClauseIntermediateClause* ReturnClause |
QuantifiedExpr | ::= | ("some" | "every") (QuantifierBinding ++ ",") "satisfies" ExprSingle |
SwitchExpr | ::= | "switch" SwitchComparand (SwitchCases | BracedSwitchCases) |
TypeswitchExpr | ::= | "typeswitch" "(" Expr ")" (TypeswitchCases | BracedTypeswitchCases) |
IfExpr | ::= | "if" "(" Expr ")" (UnbracedActions | BracedAction) |
TryCatchExpr | ::= | TryClause ((CatchClause+ FinallyClause?) | FinallyClause) |
OrExpr | ::= | AndExpr ("or" AndExpr)* |
The XQuery 4.0 operator that has lowest precedence is the comma operator, which is used to combine two operands to form a sequence. As shown in the grammar, a general expression (Expr) can consist of multiple ExprSingle operands, separated by commas.
The name ExprSingle denotes an expression that does not contain a top-level comma operator (despite its name, an ExprSingle may evaluate to a sequence containing more than one item.)
The symbol ExprSingle is used in various places in the grammar where an expression is not allowed to contain a top-level comma. For example, each of the arguments of a function call must be a ExprSingle, because commas are used to separate the arguments of a function call.
After the comma, the expressions that have next lowest precedence are FLWORExpr,QuantifiedExpr, SwitchExpr, TypeswitchExpr, IfExpr, TryCatchExpr, and OrExpr. Each of these expressions is described in a separate section of this document.
[Definition: A primary expression is an instance of the production PrimaryExpr. Primary expressions are the basic primitives of the language. They include literals, variable references, context value references, constructors, and function calls. A primary expression may also be created by enclosing any expression in parentheses, which is sometimes helpful in controlling the precedence of operators.] Node Constructors are described in 4.12 Node Constructors.Map and Array Constructors are described in 4.14.1 Maps and 4.14.2 Arrays. String Constructors are described in 4.9.3 String Constructors.
ParenthesizedExpr | ::= | "(" Expr? ")" |
Expr | ::= | (ExprSingle ++ ",") |
Parentheses may be used to override the precedence rules. For example, the expression (2 + 4) * 5 evaluates to thirty, since the parenthesized expression (2 + 4) is evaluated first and its result is multiplied by five. Without parentheses, the expression 2 + 4 * 5 evaluates to twenty-two, because the multiplication operator has higher precedence than the addition operator.
Empty parentheses are used to denote anthe empty sequence, as described in 4.7.1 Sequence Concatenation.
Functions in XQuery 4.0 arise in two ways:
A function definition contains information about a family of functions with the same name and a defined arity range. These functions are in most cases known statically (they appear in the statically known function definitions), but there may be further function definitions that are known only dynamically (appearing in the dynamically known function definitions).
Function items are XDM items that can be called using a dynamic function call. They are values that can be bound to variables, passed as arguments, returned as function results, and generally manipulated in the same way as other XDM values.
The functions defined by a statically known function definition can be invoked using a static function call. Function items corresponding to these definitions can also be obtained, as dynamic values, by evaluating a named function reference. Function items can also be obtained using the fn:function-lookup function: in this case the function name and arity do not need to be known statically, and the function definition need not be present in the static context, so long as it is in the dynamic context.
Static and dynamic function calls are described in the following sections.
The static context for an expression includes a set of statically known function definitions. Every function definition in the static context has a name (which is an expanded QName) and an arity range, which is a range of permitted arities for calls on that function. Two function definitions having the same name must not have overlapping arity ranges. This means that for a given static function call, it is possible to identify the target function definition in the static context unambiguously from knowledge of the function name and the number of supplied arguments.
A static function call is bound to a function definition in the static context by matching the name and arity. If the function call has P positional arguments followed by K keyword arguments, then the required arity is P+K, and the static context must include a function definition whose name matches the expanded QName in the function call, and whose arity range includes this required arity. This is the function chosen to be called. The result of the function is obtained by evaluating the expression that forms its implementation, with a dynamic context that provides values for all the declared parameters, initialized as described in 4.5.1.2 Evaluating Static Function Calls below.
Similarly, a named function reference of the form f#N binds to a function definition in the static context whose name matches f where MinP ≤ N and MaxP ≥ N. The result of evaluating a function reference is a function item which can be called using a dynamic function call. Function items are never variadic and their arguments are always supplied positionally. For example, the function reference fn:concat#3 returns a function item with arity 3, which is always called by supplying three positional arguments, and whose effect is the same as a static call on fn:concat with three positional arguments.
The detailed rules for evaluating static function calls and function references are defined in subsequent sections.
FunctionCall | ::= | EQNameArgumentList |
| /* xgc: reserved-function-names */ | ||
| /* gn: parens */ | ||
EQName | ::= | QName | URIQualifiedName |
ArgumentList | ::= | "(" ((PositionalArguments ("," KeywordArguments)?) | KeywordArguments)? ")" |
PositionalArguments | ::= | (Argument ++ ",") |
Argument | ::= | ExprSingle | ArgumentPlaceholder |
ExprSingle | ::= | FLWORExpr |
ArgumentPlaceholder | ::= | "?" |
KeywordArguments | ::= | (KeywordArgument ++ ",") |
KeywordArgument | ::= | EQName ":=" Argument |
[Definition: A static function call is an instance of the production FunctionCall: it consists of an EQName followed by a parenthesized list of zero or more arguments.].
The EQName is expanded using the default function namespace rule.
The argument list consists of zero or more positional arguments, followed by zero or more keyword arguments.
[Definition: An argument to a function call is either an argument expression or an ArgumentPlaceholder (?); in both cases it may either be supplied positionally, or identified by a name (called a keyword).]
This section is concerned with static function calls in which none of the arguments are ArgumentPlaceholders. Calls using one or more ArgumentPlaceholders are covered in the section 4.5.4 Partial Function Application.
The expanded QName used as the function name and the number of arguments used in the static function call (the required arity) must match the name and arity range of a function definition in the static context using the rules defined in the previous section; if there is no match, a static error is raised [err:XPST0017].
Evaluation of static function calls is described in 4.5.1.2 Evaluating Static Function Calls .
Since the arguments of a function call are separated by commas, any argument expression that contains a top-level comma operator must be enclosed in parentheses. Here are some illustrative examples of static function calls:
my:three-argument-function(1, 2, 3) denotes a static function call with three positional arguments. The corresponding function declaration must define at least three parameters, and may define more, provided they are optional.
my:two-argument-function((1, 2), 3) denotes a static function call with two arguments, the first of which is a sequence of two values. The corresponding function declaration must define at least two parameters, and may define more, provided they are optional.
my:two-argument-function(1, ()) denotes a static function call with two arguments, the second of which is anthe empty sequence.
my:one-argument-function((1, 2, 3)) denotes a static function call with one argument that is a sequence of three values.
my:one-argument-function(( )) denotes a static function call with one argument that is anthe empty sequence.
my:zero-argument-function( ) denotes a static function call with zero arguments.
lang(node := $n, language := 'de') is a static function call with two keyword arguments. The corresponding function declaration defines two parameters, a required parameter language and an optional parameter node. This call supplies values for both parameters. It is equivalent to the call fn:lang('de', $n). Note that the keyword arguments are in a different order from the parameter declarations.
sort(//employee, key := fn($e) { xs:decimal($e/salary) }) is a static function call with one positional argument and one keyword argument. The corresponding function declaration defines three parameters, a required parameter $input, an optional parameter $collation, and an optional parameter $key This call supplies values for the first and third parameters, leaving the second parameter ($collation) to take its default value. The default value of the $collation parameter is given as fn:default-collation(), so the value supplied to the function is the default collation from the dynamic context of the caller. It is equivalent to the call fn:sort(//employee, fn:default-collation(), fn($e) { xs:decimal($e/salary) }).
An EQName in a KeywordArgument is expanded using the no-namespace rule. The keywords used in a function call (after expansion) must be distinct [err:XPST0017].
A dynamic function call consists of a base expression that returns the function and a parenthesized list of zero or more arguments (argument expressions or ArgumentPlaceholders).
A dynamic function call is evaluated as described in 4.5.3.1 Evaluating Dynamic Function Calls.
The following are examples of dynamic function calls:
This example calls the function contained in $f, passing the arguments 2 and 3:
$f(2, 3)
This example fetches the second item from sequence $f, treats it as a function and calls it, passing an xs:string argument:
$f[2]("Hi there")This example calls the function $f passing no arguments, and filters the result with a positional predicate:
$f()[2]
Note:
Arguments in a dynamic function call are always supplied positionally.
Changes in 4.0 (next | previous)
A dynamic function call can now be applied to a sequence of functions, and in particular to anthe empty sequence. This makes it easier to chain a sequence of calls. [Issue 1240 ]
This section applies to dynamic function calls whose arguments do not include an ArgumentPlaceholder. For function calls that include a placeholder, see 4.5.4 Partial Function Application.
A dynamic function call is an expression that is evaluated by calling a function item, which is typically obtained dynamically.
When a dynamic function call FC is evaluated, the result is obtained as follows:
The base expression of the function call is evaluated. If this is not of type function(*)* (a sequence of zero or more function items) then a type error is raised [err:XPTY0004].
The result of the dynamic function call is the sequence concatenation of the results of applying each function item individually, retaining order. That is, the result of F(X, Y, ...) is for $FI in F return $FI(X, Y, ...). The result of a dynamic function call applied to a single function item FI is defined by the rules that follow.
[err:XPTY0004]. If the arity of FI does not match the number of arguments in the ArgumentList, a type error is raised [err:XPTY0004].
Argument expressions are evaluated, producing argument values. The order of argument evaluation is implementation-dependent and an argument need not be evaluated if the function body can be evaluated without evaluating that argument.
Each argument value is converted to the corresponding parameter type in FI’s signature by applying the coercion rules, resulting in a converted argument value
If FI is a map, it is evaluated as described in 4.14.1.2 Maps as Functions.
If FI is an array, it is evaluated as described in 4.14.2.2 Arrays as Functions.
If FI’s body is an XQuery 4.0 expression (for example, if FI is a user-defined function or an anonymous function, or a partial application of such a function):
FI’s body is evaluated. The static context for this evaluation is the static context of the XQuery 4.0 expression. The dynamic context for this evaluation is obtained by taking the dynamic context of the module that contains the FunctionBody, and making the following changes:
The focus (context value, context position, and context size) is absentDM.
In the variable values component of the dynamic context, each converted argument value is bound to the corresponding parameter name.
When this is done, the converted argument values retain their dynamic types, even where these are subtypes of the declared parameter types. For example, a function with a parameter $p of type xs:decimal can be called with an argument of type xs:integer, which is derived from xs:decimal. During the processing of this function call, the value of $p inside the body of the function retains its dynamic type of xs:integer.
FI’s nonlocal variable bindings are also added to the variable values. (Note that the names of the nonlocal variables are by definition disjoint from the parameter names, so there can be no conflict.)
The value returned by evaluating the function body is then converted to the declared return type of FI by applying the coercion rules. The result is then the result of evaluating FC.
As with argument values, the value returned by a function retains its dynamic type, which may be a subtype of the declared return type of FI. For example, a function that has a declared return type of xs:decimal may in fact return a value of dynamic type xs:integer.
If the implementation of FI is not an XQuery 4.0 expression (for example, if FI is a system functionor an external function), the body of the function is evaluated, and the result is converted to the declared return type, in the same way as for a static function call (see 4.5.1.1 Static Function Call Syntax).
Errors may be raised in the same way.
$incr is a nonlocal variable that is available within the function because its variable binding has been added to the variable values of the function. Even though the parameter and return type of this function are both xs:decimal, the more specific type xs:integer is preserved in both cases.
let $incr := 1
let $f := function($i as xs:decimal) as xs:decimal { $i + $incr }
return $f(5)
The following example will raise a type error [err:XPDY0002]:
let $vat := function() { @vat + @price }
return doc('wares.xml')/shop/article/$vat()Instead, the context value can be used as an argument to the anonymous function:
let $vat := function($art) { $art/@vat + $art/@price }
return doc('wares.xml')/shop/article/$vat(.)Alternatively, the value can be referenced as a nonlocal variable binding:
let $ctx := doc('wares.xml')/shop/article
let $vat := function() { for $a in $ctx return $a/@vat + $a/@price }
return $vat()Finally, a focus function can be used. This binds the value of the argument to the context value within the function body:
let $vat := function { @vat + @price }
return $vat(doc('wares.xml')/shop/article)
A dynamic function call can call zero or more functions with the same arguments, returning the sequence concatenation of the result. For example:
(abs#1, round#1, floor#1, ceiling#1)(3.2)
returns the sequence (3.2, 3, 3, 4).
A common case for supplying a sequence of functions arises when the functions are arrays. For example:
csv-to-arrays( string-join(("a,b,c", "p,q,r", "x,y,z"), char(10)) ) (2)returns the sequence ("b", "q", "y").
If the base expression evaluates to anthe empty sequence, the result is anthe empty sequence.
Note:
Keyword arguments are not allowed in a dynamic function call.
Changes in 4.0 (next | previous)
Path expressions are extended to handle JNodes (found in trees of maps and arrays) as well as XNodes (found in trees representing parsed XML). [Issue 2054 ]
PathExpr | ::= | AbsolutePathExpr |
| /* xgc: leading-lone-slash */ | ||
AbsolutePathExpr | ::= | ("/" RelativePathExpr?) | ("//" RelativePathExpr) |
RelativePathExpr | ::= | StepExpr (("/" | "//") StepExpr)* |
[Definition: A path expression is either an absolute path expression or a relative path expression ]
[Definition: An absolute path expression is an instance of the production AbsolutePathExpr: it consists of either (a) the operator / followed by zero or more operands separated by / or // operators, or (b) the operator // followed by one or more operands separated by / or // operators.]
[Definition: A relative path expression is a non-trivial instance of the production RelativePathExpr: it consists of two or more operand expressions separated by / or // operators.]
[Definition: The operands of a path expression are conventionally referred to as steps.]
Note:
The term step must not be confused with axis step. A step can be any kind of expression, often but not necessarily an axis step, while an axis step can be used in any expression context, not necessarily as a step in a path expression.
A path expression is typically used to locate GNodes within GTrees.
Note:
Note the terminology:
The following definitions are copied from the data model specification, for convenience:
[Definition: A tree that is rooted at a parentless JNode is referred to as a JTree.]
[Definition: A tree that is rooted at a parentless XNode is referred to as an XTree.]
[Definition: The term generic node or GNode is a collective term for XNodes (more commonly called simply nodes) representing the parts of an XML document, and JNodes, often used to represent the parts of a JSON document.]
[Definition: The term GTree means JTree or XTree.]
[Definition: A JNode is a kind of item used to represent a value within the context of a tree of maps and arrays. A root JNode represents a map or array; a non-root JNode represents a member of an array or an entry in a map.]
[Definition: The term GTree means JTree or XTree.]
Absolute path expressions (those starting with an initial / or //), start their selection from the root GNode of a GTree; relative path expressions (those without a leading / or //) start from the context value.
AxisStep | ::= | (AbbreviatedStep | FullStep) Predicate* |
AbbreviatedStep | ::= | ".." | ("@" NodeTest) | SimpleNodeTest |
FullStep | ::= | AxisNodeTest |
Axis | ::= | ("ancestor" | "ancestor-or-self" | "attribute" | "child" | "descendant" | "descendant-or-self" | "following" | "following-or-self" | "following-sibling" | "following-sibling-or-self" | "parent" | "preceding" | "preceding-or-self" | "preceding-sibling" | "preceding-sibling-or-self" | "self") "::" |
NodeTest | ::= | UnionNodeTest | SimpleNodeTest |
Predicate | ::= | "[" Expr "]" |
[Definition: An axis step is an instance of the production AxisStep: it is an expression that returns a sequence of GNodes that are reachable from a starting GNode via a specified axis. An axis step has three parts: an axis, which defines the direction of movement for the step, a node test, which selects GNodes based on their properties, and zero or more predicates which are used to filter the results.]
Note:
An axis step is an expression in its own right. While axis steps are often used as the operands of path expressions, they can also appear in other contexts (without a / or // operator); equally, the operands of a path expression can be any expression, not restricted to an axis step.
If the context value for an axis step includes a map or array, this is implicitly converted to a JNode as if by applying the fn:jtree function. If, after this conversion, the sequence contains a value that is not a GNode, a type error is raised [err:XPTY0020]. The result of evaluating the axis step is a sequence of zero or more GNodes.
The axis stepS is equivalent to ./S. Thus, if the context value is a sequence containing multiple GNodes, the semantics of a axis step are equivalent to a path expression in which the step is always applied to a single GNode. The following description therefore explains the semantics for the case where the context value is a single GNode, called the origin.
Note:
The equivalence of a axis stepS to the path expression./S means that the resulting GNode sequence is returned in document order.
In the abbreviated syntax for a step, the axis can be omitted and other shorthand notations can be used as described in 4.6.8 Abbreviated Syntax.
The unabbreviated syntax for an axis step consists of the axis name and node test separated by a double colon. The result of the step consists of the GNodes reachable from the origin via the specified axis that match the node test. For example, the step child::para selects the para element children of the origin XNode: child is the name of the axis, and para is the name of the element nodes to be selected on this axis. The available axes are described in 4.6.5.1 Axes. The available node tests are described in 4.6.5.2 Node Tests. Examples of steps are provided in 4.6.7 Unabbreviated Syntax and 4.6.8 Abbreviated Syntax.
Axis | ::= | ("ancestor" | "ancestor-or-self" | "attribute" | "child" | "descendant" | "descendant-or-self" | "following" | "following-or-self" | "following-sibling" | "following-sibling-or-self" | "parent" | "preceding" | "preceding-or-self" | "preceding-sibling" | "preceding-sibling-or-self" | "self") "::" |
An axis is essentially a function that takes a GNode (the origin) as input, and delivers a sequence of GNodes (always from within the same GTree as the origin) as its result.
XQuery supports the following axes:
The child axis contains the children of the origin.
If the origin is an XNode, these are the XNodes returned by the [XDM 4.0] section 7.6.3 children Accessor accessor.
Note:
In an XTree, only document nodes and element nodes have children. If the origin is any other kind of XNode, or if the origin is an empty document or element node, then the child axis returns anthe empty sequence. The children of a document node or element node may be element, processing instruction, comment, or text nodes. Attribute, namespace, and document nodes can never appear as children.
If the origin is a JNode, these are the JNodes returned by the j-childrenDM accessor.
The descendant axis is defined as the transitive closure of the child axis; it contains the descendants of the origin (the children, the children of the children, and so on).
More formally, $node/descendant::gnode() delivers the result of fn:transitive-closure($node, fn { child::gnode() }).
The descendant-or-self axis contains the origin and the descendants of the origin.
More formally, $node/descendant-or-self::gnode() delivers the result of $node/(. | descendant::gnode()).
The parent axis returns the parent of the origin.
If the origin is an XNode, this is the result of the [XDM 4.0] section 7.6.11 parent Accessor accessor.
If the origin is a JNode, this is the value of the ·parent· property of the origin.
If the GNode has no parent, the axis returns anthe empty sequence.
Note:
An attribute node may have an element node as its parent, even though the attribute node is not a child of the element node.
The ancestor axis is defined as the transitive closure of the parent axis; it contains the ancestors of the origin (the parent, the parent of the parent, and so on).
More formally, $node/ancestor::gnode() delivers the result of fn:transitive-closure($node, fn { parent::gnode() }).
Note:
The ancestor axis includes the root GNode of the GTree in which the origin is found, unless the origin is itself the root GNode.
The ancestor-or-self axis contains the origin and the ancestors of the origin; thus, the ancestor-or-self axis will always include the root.
More formally, $node/ancestor-or-self::gnode() delivers the result of $node/(. | ancestor::gnode()).
The following-sibling axis returns the origin’s following siblings, that is, those children of the origin’s parent that occur after the origin in document order. If the origin is an attribute or namespace node, the following-sibling axis is empty.
More formally, $node/following-sibling::gnode() delivers the result of fn:siblings($node)[. >> $node]).
The following-sibling-or-self axis contains the origin, together with the contents of the following-sibling axis.
More formally, $node/following-sibling-or-self::gnode() delivers the result of fn:siblings($node)[not(. << $node)]
The preceding-sibling axis returns the origin’s preceding siblings, that is, those children of the origin’s parent that occur before the context node in document order. If the origin is an attribute or namespace node, the preceding-sibling axis is empty.
More formally, $node/preceding-sibling::gnode() delivers the result of fn:siblings($node)[. << $node].
The preceding-sibling-or-self axis contains the origin, together with the contents of the preceding-sibling axis.
More formally, $node/preceding-sibling-or-self::gnode() delivers the result of fn:siblings($node)[not(. >> $node).
The following axis contains all descendants of the root of the GTree in which the origin is found, are not descendants of the origin, and occur after the origin in document order.
More formally, $node/following::gnode() delivers the result of $node/ancestor-or-self::gnode()/following-sibling::gnode()/descendant-or-self::gnode()
The following-or-self axis contains the origin, together with the contents of the following axis.
More formally, $node/following-or-self::gnode() delivers the result of $node/(. | following::gnode()).
The preceding axis returns all descendants of the root of the GTree in which the origin is found, are not ancestors of the origin, and occur before the origin in document order.
More formally, $node/preceding::gnode() delivers the result of $node/ancestor-or-self::gnode()/preceding-sibling::gnode()/descendant-or-self::gnode().
The preceding-or-self axis returns the origin, together with the contents of the preceding axis.
More formally, $node/preceding-or-self::gnode() delivers the result of $node/(. | preceding::gnode()).
The attribute axis is defined only for XNodes. It returns the attributes of the origin, which are the nodes returned by the [XDM 4.0] section 7.6.1 attributes Accessor; the axis will be empty unless the context node is an element.
If the attribute axis is applied to a JNode, a type error [err:XPTY0004] is raised.
The self axis contains just the origin itself.
The self axis is primarily useful when testing whether the origin satisfies particular conditions, for example if ($x[self::chapter]).
More formally, $node/self::gnode() delivers the result of $node.
Axes can be categorized as forward axes and reverse axes. An axis that only ever contains the origin or nodes that are after the context node in document order is a forward axis. An axis that only ever contains the context node or nodes that are before the context node in document order is a reverse axis.
The parent, ancestor, ancestor-or-self, preceding, preceding-or-self, preceding-sibling, and preceding-sibling-or-self axes are reverse axes; all other axes are forward axes.
The ancestor, descendant, following, preceding and self axes partition a GTree (ignoring attribute nodes): they do not overlap and together they contain all the GNodes in the GTree.
[Definition: Every axis has a principal node kind. If an axis can contain elements, then the principal node kind is element; otherwise, it is the kind of nodes that the axis can contain.] Thus:
For the attribute axis, the principal node kind is attribute.
For all other axes, the principal node kind is element.
A type test is a node test that selects JNodes or XNodes based on their type.
For example:
element(N) (short for child::element(N)) selects elements named N.
attribute(*, xs:integer)selects attribute nodes whose type annotation is xs:integer.
text() selects text nodes.
jnode("id") selects JNodes having the ·selector· property "id".
jnode(*, map(*)) selects JNodes whose ·content· property is an instance of the type map(*).
The syntax and semantics of NodeKindTest and JNodeType are described in 3.1 Sequence Types and 3.1.2 Sequence Type Matching.
Shown below are further examples of type tests that might be used in path expressions selecting within an XTree:
node() matches any XNode.
text() matches any text node.
comment() matches any comment node.
namespace-node() matches any namespace node.
element() matches any element node.
schema-element(person) matches any element node whose name is person (or is in the substitution group headed by person), and whose type annotation is the same as (or is derived from) the declared type of the person element in the in-scope element declarations.
element(person) matches any element node whose name is person, regardless of its type annotation.
element(doctor|nurse) matches any element node whose name is doctor or nurse, regardless of its type annotation.
element(person, surgeon) matches any non-nilled element node whose name is person, and whose type annotation is surgeon or is derived from surgeon.
element(doctor|nurse, medical-staff) matches any non-nilled element node whose name is doctor or nurse, and whose type annotation is medical-staff or is derived from medical-staff.
element(*, surgeon) matches any non-nilled element node whose type annotation is surgeon (or is derived from surgeon), regardless of its name.
attribute() matches any attribute node.
attribute(price) matches any attribute whose name is price, regardless of its type annotation.
attribute(*, xs:decimal) matches any attribute whose type annotation is xs:decimal (or is derived from xs:decimal), regardless of its name.
document-node() matches any document node.
document-node(element(book)) matches any document node whose children consist of a single element node that satisfies the ElementTestelement(book), interleaved with zero or more comments and processing instructions, and no text nodes.
document-node(book) is an abbreviation for document-node(element(book)).
The following examples show type type tests that might be used in path expressions selecting within a JTree:
jnode(*, array(*)) matches any JNode whose ·content· is an array.
jnode(*, record(longitude, latitude, *)) matches any JNode whose ·content· is a map having entries with keys "longitude" and "latitude".
jnode(*, empty-sequence()) matches any JNode whose ·content· is anthe empty sequence.
jnode(*, xs:date) matches any JNode whose ·content· is an instance of xs:date.
Changes in 4.0 (next | previous)
The rules for reporting type errors during static analysis have been changed so that a processor has more freedom to report errors in respect of constructs that are evidently wrong, such as @price/@value, even though dynamic evaluation is defined to return anthe empty sequence rather than an error. [Issue 602 PR 603 25 July 2023]
Certain axis steps, given an inferred type for the context value, are classified as implausible. During the static analysis phase, a processor may (subject to the rules in 2.5.6 Implausible Expressions) report a static error when such axis steps are encountered: [err:XPTY0144].
More specifically, an axis step is classified as implausible if any of the following conditions applies:
The inferred item type of the context value is a node kind for which the specified axis is always empty: for example, the inferred item type of the context value is attribute() and the axis is child.
The node test exclusively selects node kinds that cannot appear on the specified axis: for example, the axis is child and the node test is document-node().
In a schema-aware environment, when using the child, descendant, descendant-or-self, or attribute axes, the inferred item type of the context value has a content type that does not allow any node matching the node test to be present on the relevant axis. For example, if the inferred item type of the context value is schema-element(list) and the relevant element declaration (taking into account substitution group membership and wildcards) only allows item children, the axis step child::li will never select anything and is therefore classified as implausible.
Examples of implausible axis steps include the following:
@code/text(): attributes cannot have text node children.
/@code: document nodes cannot have attributes.
ancestor::text(): the ancestor axis never returns text nodes.
element(*)/child::map: the child axis starting at an element node will never select a map.
Note:
Processors may choose not to classify the expression /.. as implausible, since XSLT 1.0 users were sometimes advised to use this construct as an explicit way of denoting the empty sequence.
This section provides a number of examples of path expressions in which the axis is explicitly specified in each step. The syntax used in these examples is called the unabbreviated syntax. In many common cases, it is possible to write path expressions more concisely using an abbreviated syntax, as explained in 4.6.8 Abbreviated Syntax.
These examples assume that the context value is a single node, referred to as the context node.
child::para selects the para element children of the context node.
child::(para|bullet) selects the para and bullet element children of the context node.
child::* selects all element children of the context node.
child::text() selects all text node children of the context node.
child::(text()|comment()) selects all text node and comment node children of the context node.
child::node() selects all the children of the context node. Note that no attribute nodes are returned, because attributes are not children.
attribute::name selects the name attribute of the context node.
attribute::* selects all the attributes of the context node.
parent::node() selects the parent of the context node. If the context node is an attribute node, this expression returns the element node (if any) to which the attribute node is attached.
descendant::para selects the para element descendants of the context node.
ancestor::div selects all div ancestors of the context node.
ancestor-or-self::div selects the div ancestors of the context node and, if the context node is a div element, the context node as well.
descendant-or-self::para selects the para element descendants of the context node and, if the context node is a para element, the context node as well.
self::para selects the context node if it is a para element, and otherwise returns anthe empty sequence.
self::(chapter|appendix) selects the context node if it is a chapter or appendix element, and otherwise returns anthe empty sequence.
child::chapter/descendant::para selects the para element descendants of the chapter element children of the context node.
child::*/child::para selects all para grandchildren of the context node.
/ selects the root of the tree that contains the context node, but raises a dynamic error if this root is not a document node.
/descendant::para selects all the para elements in the same document as the context node.
/descendant::list/child::member selects all the member elements that have a list parent and that are in the same document as the context node.
child::para[position() = 1] selects the first para child of the context node.
child::para[position() = last()] selects the last para child of the context node.
child::para[position() = last()-1] selects the last but one para child of the context node.
child::para[position() > 1] selects all the para children of the context node other than the first para child of the context node.
following-sibling::chapter[position() = 1] selects the next chapter sibling of the context node.
following-sibling::(chapter|appendix)[position() = 1] selects the next sibling of the context node that is either a chapter or an appendix.
preceding-sibling::chapter[position() = 1] selects the previous chapter sibling of the context node.
/descendant::figure[position() = 42] selects the forty-second figure element in the document containing the context node.
/child::book/child::chapter[position() = 5]/child::section[position() = 2] selects the second section of the fifth chapter of the book whose parent is the document node that contains the context node.
child::para[attribute::type eq "warning"] selects all para children of the context node that have a type attribute with value warning.
child::para[attribute::type eq 'warning'][position() = 5] selects the fifth para child of the context node that has a type attribute with value warning.
child::para[position() = 5][attribute::type eq "warning"] selects the fifth para child of the context node if that child has a type attribute with value warning.
child::chapter[child::title = 'Introduction'] selects the chapter children of the context node that have one or more title children whose typed value is equal to the string Introduction.
child::chapter[child::title] selects the chapter children of the context node that have one or more title children.
child::*[self::chapter or self::appendix] selects the chapter and appendix children of the context node.
child::*[self::(chapter|appendix)][position() = last()] selects the last chapter or appendix child of the context node.
AbbreviatedStep | ::= | ".." | ("@" NodeTest) | SimpleNodeTest |
NodeTest | ::= | UnionNodeTest | SimpleNodeTest |
SimpleNodeTest | ::= | TypeTest | Selector |
TypeTest | ::= | NodeKindTest | JNodeType |
Selector | ::= | EQName | Wildcard | ("get" "(" ExprSingle ")") |
EQName | ::= | QName | URIQualifiedName |
Wildcard | ::= | "*" |
| /* ws: explicit */ | ||
ExprSingle | ::= | FLWORExpr |
The abbreviated syntax for a step permits the following abbreviations:
The attribute axis attribute:: can be abbreviated by @. For example, the expression para[@type = "warning"] is short for child::para[attribute::type = "warning"] and so selects para children with a type attribute with value equal to warning.
If the axis name is omitted from an axis step, the default axis is child, with two exceptions: (1) if the NodeTest in an axis step contains an AttributeTest or SchemaAttributeTest then the default axis is attribute; (2) if the NodeTest in an axis step is a NamespaceNodeTestthen a static error is raised [err:XQST0134].
Note:
The namespace axis is deprecated as of XPath 2.0, but is required in some languages that use XPath, including XSLT.
For example, the path expression section/para is an abbreviation for child::section/child::para, and the path expression section/@id is an abbreviation for child::section/attribute::id. Similarly, section/attribute(id) is an abbreviation for child::section/attribute::attribute(id). Note that the latter expression contains both an axis specification and a node test.
Similarly, within a JTree rooted at an array, the expression get(1)/parts/get(2)/part-no gets the first member of the top-level array (presumably a map), then the "parts" entry within this map (presumably an array), then the second member of this array (presumably a map), and finally the part-no entry within this map.
Note:
The same selection could be made using the lookup expression ?1?parts?2?part-no. The main difference is that path expressions offer more flexibility in being able to navigate around the containing JTree. Also, the lookup expression $a?1 fails if the array index is out of bounds; the path expression $a/get(1) (or $a/*[1]) instead returns anthe empty sequence.
Note:
An abbreviated axis step that omits the axis name must use a SimpleNodeTest rather than a UnionNodeTest. This means that a construct such as (ul|ol) is treated as an abbreviation for (child::ul|child::ol) rather than child::(ul|ol). Since the two constructs have exactly the same semantics, this is not actually a restriction.
A step consisting of .. is short for parent::gnode(). For example (assuming the context item is an XNode), ../title is short for parent::gnode()/child::title and so will select the title children of the parent of the context node.
Similarly, if $dateOfBirth is a JNode resulting from the expression $map/get("date of birth"), then $dateOfBirth/../gender will select the entry having key "gender" within $map.
Note:
The expression ., known as a context value reference, is a primary expression, and is described in 4.2.3 Context Value References.
Here are some examples of path expressions that use the abbreviated syntax. These examples assume that the context value is a single XNode, referred to as the context node:
para selects the para element children of the context node.
* selects all element children of the context node.
text() selects all text node children of the context node.
@name selects the name attribute of the context node.
@(id|name) selects the id and name attributes of the context node.
@* selects all the attributes of the context node.
para[1] selects the first para child of the context node.
para[last()] selects the last para child of the context node.
*/para selects all para grandchildren of the context node.
/book/chapter[5]/section[2] selects the second section of the fifth chapter of the book whose parent is the document node that contains the context node.
chapter//para selects the para element descendants of the chapter element children of the context node.
//para selects all the para descendants of the root document node and thus selects all para elements in the same document as the context node.
//@version selects all the version attribute nodes that are in the same document as the context node.
//list/member selects all the member elements in the same document as the context node that have a list parent.
.//para selects the para element descendants of the context node.
.. selects the parent of the context node.
../@lang selects the lang attribute of the parent of the context node.
para[@type = "warning"] selects all para children of the context node that have a type attribute with value warning.
para[@type = "warning"][5] selects the fifth para child of the context node that has a type attribute with value warning.
para[5][@type = "warning"] selects the fifth para child of the context node if that child has a type attribute with value warning.
chapter[title = "Introduction"] selects the chapter children of the context node that have one or more title children whose typed value is equal to the string Introduction.
chapter[title] selects the chapter children of the context node that have one or more title children.
employee[@secretary and @assistant] selects all the employee children of the context node that have both a secretary attribute and an assistant attribute.
book/(chapter|appendix)/section selects every section element that has a parent that is either a chapter or an appendix element, that in turn is a child of a book element that is a child of the context node.
If E is any expression that returns a sequence of nodes, then the expression E/. returns the same nodes in document order, with duplicates eliminated based on node identity.
The following examples use abbreviated paths to access data within the JTree obtained by parsing the JSON text:
[
{ "first": "John",
"last": "Baker",
"date of birth": "2003-04-19",
"occupation": "cook"},
{ "first": "Mary",
"last": "Smith",
"date of birth": "2006-08-12",
"occupation": "teacher"},
]get(1)/first returns a JNode whose ·content· is the string "John".
//first[. = "Mary"]/../last returns a JNode whose ·content· is the string "Smith".
//first[. = "Mary"]/../get("date of birth") returns a JNode whose ·content· is the string "2006-08-12".
//*[occupation = "cook"]!`{first} {last}` returns the string "John Baker".
//*[occupation = "cook"]/following-sibling::*[1]!`{first} {last}` returns the string "Mary Smith".
//*[last = "Smith"]/../get(1)/last returns the string "Baker".
//record(first, last, *) ! string(last) returns the sequence of two strings "Baker", "Smith".
XQuery 4.0 supports operators to construct, filter, and combine sequences of items. Sequences are never nested—for example, combining the values 1, (2, 3), and ( ) into a single sequence results in the sequence (1, 2, 3).
Expr | ::= | (ExprSingle ++ ",") |
ExprSingle | ::= | FLWORExpr |
[Definition: A sequence expression is a non-trivial instance of the production rule Expr, that is, an expression containing two or more instances of the production ExprSingle separated by the comma operator.]
The result of a sequence expression is the sequence concatenation of the values of its operands. See
[Definition: A comma operator is a comma used specifically as the operator in a sequence expression.]
Empty parentheses can be used to denote anthe empty sequence.
A sequence may contain duplicate items, but a sequence is never an item in another sequence. When a new sequence is created by concatenating two or more input sequences, the new sequence contains all the items of the input sequences and its length is the sum of the lengths of the input sequences.
[Definition: The sequence concatenation of a number of sequences S1, S2, ... Sn is defined to be the sequence formed from the items of S1, followed by the items from S2, and so on, retaining order.] The comma operator returns the sequence concatenation of its two operands; repeated application (for example $s1, $s2, $s3, $s4) delivers the sequence concatenation of multiple sequences.
Note:
In places where the grammar calls for ExprSingle, such as the arguments of a function call, any expression that contains a top-level comma operator must be enclosed in parentheses.
Here are some examples of expressions that construct sequences:
The result of this expression is a sequence of five integers:
(10, 1, 2, 3, 4)
This expression combines four sequences of length one, two, zero, and two, respectively, into a single sequence of length five. The result of this expression is the sequence 10, 1, 2, 3, 4.
(10, (1, 2), (), (3, 4))
The result of this expression is a sequence containing all salary children of the context node followed by all bonus children.
(salary, bonus)
Assuming that $price is bound to the value 10.50, the result of this expression is the sequence 10.50, 10.50.
($price, $price)
RangeExpr | ::= | AdditiveExpr ("to" AdditiveExpr)? |
AdditiveExpr | ::= | MultiplicativeExpr (("+" | "-") MultiplicativeExpr)* |
[Definition: A range expression is a non-trivial instance of the production RangeExpr. A range expression is used to construct a sequence of integers.] Each of the operands is converted as though it was an argument of a function with the expected parameter type xs:integer?. If either operand is anthe empty sequence, or if the integer derived from the first operand is greater than the integer derived from the second operand, the result of the range expression is anthe empty sequence. If the two operands convert to the same integer, the result of the range expression is that integer. Otherwise, the result is a sequence containing the two integer operands and every integer between the two operands, in increasing order.
The following examples illustrate the semantics:
1 to 4 returns the sequence 1, 2, 3, 4
10 to 10 returns the singleton sequence 10
10 to 1 returns the empty sequence
-13 to -10 returns the sequence -13, -12, -11, -10
More formally, a range expression is evaluated as follows:
Each of the operands of the to operator is converted as though it was an argument of a function with the expected parameter type xs:integer?.
If either operand is anthe empty sequence, or if the integer derived from the first operand is greater than the integer derived from the second operand, the result of the range expression is anthe empty sequence.
If the two operands convert to the same integer, the result of the range expression is that integer.
Otherwise, the result is a sequence containing the two integer operands and every integer between the two operands, in increasing order.
The following examples illustrate the use of range expressions.
This example uses a range expression as one operand in constructing a sequence. It evaluates to the sequence 10, 1, 2, 3, 4.
(10, 1 to 4)
This example selects the first four items from an input sequence:
$input[1 to 4]
This example returns the sequence (0, 0.1, 0.2, 0.3, 0.5):
$x = (1 to 5) ! . * 0.1
This example constructs a sequence of length one containing the single integer 10.
10 to 10
The result of this example is a sequence of length zero.
15 to 10
This example uses the fn:reverse function to construct a sequence of six integers in decreasing order. It evaluates to the sequence 15, 14, 13, 12, 11, 10.
reverse(10 to 15)
Note:
To construct a sequence of integers based on steps other than 1, use the fn:slice function, as defined in 14.1 General functions and operators on sequences FO31.
XQuery 4.0 provides binary arithmetic operators for addition, subtraction, multiplication, division, and modulus:
AdditiveExpr | ::= | MultiplicativeExpr (("+" | "-") MultiplicativeExpr)* |
MultiplicativeExpr | ::= | UnionExpr (("*" | "×" | "div" | "÷" | "idiv" | "mod") UnionExpr)* |
UnionExpr | ::= | IntersectExceptExpr (("union" | "|") IntersectExceptExpr)* |
In addition, unary operators are provided for addition and subtraction:
UnaryExpr | ::= | ("-" | "+")* ValueExpr |
ValueExpr | ::= | ValidateExpr | ExtensionExpr | SimpleMapExpr |
ValidateExpr | ::= | "validate" (ValidationMode | ("type" TypeName))? "{" Expr "}" |
ExtensionExpr | ::= | Pragma+ "{" Expr? "}" |
SimpleMapExpr | ::= | PathExpr ("!" PathExpr)* |
A subtraction operator must be preceded by whitespace if it could otherwise be interpreted as part of the previous token. For example, a-b will be interpreted as a name, but a - b and a -b will be interpreted as arithmetic expressions. (See A.3.4 Whitespace Rules for further details on whitespace handling.)
The arithmetic operator symbols * and U+00D7 (MULTIPLICATION SIGN, ×) are interchangeable, and denote multiplication.
The arithmetic operator symbols div and U+00F7 (DIVISION SIGN, ÷) are interchangeable, and denote division.
If an AdditiveExpr contains more than two MultiplicativeExprs, they are grouped from left to right. So, for instance,
A - B + C - D
is equivalent to
((A - B) + C) - D
Similarly, the operands of a MultiplicativeExpr are grouped from left to right.
The first step in evaluating an arithmetic expression is to evaluate its operand (for a unary operator) or operands (for a binary operator). The order in which the operands are evaluated is implementation-dependent.
Each operand is evaluated by applying the following steps, in order:
Atomization is applied to the operand. The result of this operation is called the atomized operand.
If the atomized operand is anthe empty sequence, the result of the arithmetic expression is anthe empty sequence, and the implementation need not evaluate the other operand or apply the operator. However, an implementation may choose to evaluate the other operand in order to determine whether it raises an error.
If the atomized operand is a sequence of length greater than one, a type error is raised [err:XPTY0004].
If the atomized operand is of type xs:untypedAtomic, it is cast to xs:double. If the cast fails, a dynamic error is raised. [err:FORG0001]FO40
If, after this process, both operands of a binary arithmetic operator are instances of xs:numeric but have different primitive types, they are coerced to a common type by applying the following rules:
If either of the items is of type xs:double, then both the values are cast to type xs:double.
Otherwise, if either of the items is of type xs:float, then both the values are cast to type xs:float.
Otherwise, no casting takes place: the values remain as xs:decimal.
After this preparation, the arithmetic expression is evaluated by applying the appropriate function listed in the table below. The definitions of these functions are found in [Functions and Operators 4.0].
| Expression | Type of A | Function | Result type |
|---|---|---|---|
| + A | xs:numeric | op:numeric-unary-plus(A) | xs:numeric |
| - A | xs:numeric | op:numeric-unary-minus(A) | xs:numeric |
| Expression | Type of A | Type of B | Function | Result type |
|---|---|---|---|---|
| A + B | xs:numeric | xs:numeric | op:numeric-add(A, B) | xs:numeric |
| A + B | xs:date | xs:yearMonthDuration | op:add-yearMonthDuration-to-date(A, B) | xs:date |
| A + B | xs:yearMonthDuration | xs:date | op:add-yearMonthDuration-to-date(B, A) | xs:date |
| A + B | xs:date | xs:dayTimeDuration | op:add-dayTimeDuration-to-date(A, B) | xs:date |
| A + B | xs:dayTimeDuration | xs:date | op:add-dayTimeDuration-to-date(B, A) | xs:date |
| A + B | xs:time | xs:dayTimeDuration | op:add-dayTimeDuration-to-time(A, B) | xs:time |
| A + B | xs:dayTimeDuration | xs:time | op:add-dayTimeDuration-to-time(B, A) | xs:time |
| A + B | xs:dateTime | xs:yearMonthDuration | op:add-yearMonthDuration-to-dateTime(A, B) | xs:dateTime |
| A + B | xs:yearMonthDuration | xs:dateTime | op:add-yearMonthDuration-to-dateTime(B, A) | xs:dateTime |
| A + B | xs:dateTime | xs:dayTimeDuration | op:add-dayTimeDuration-to-dateTime(A, B) | xs:dateTime |
| A + B | xs:dayTimeDuration | xs:dateTime | op:add-dayTimeDuration-to-dateTime(B, A) | xs:dateTime |
| A + B | xs:yearMonthDuration | xs:yearMonthDuration | op:add-yearMonthDurations(A, B) | xs:yearMonthDuration |
| A + B | xs:dayTimeDuration | xs:dayTimeDuration | op:add-dayTimeDurations(A, B) | xs:dayTimeDuration |
| A - B | xs:numeric | xs:numeric | op:numeric-subtract(A, B) | xs:numeric |
| A - B | xs:date | xs:date | op:subtract-dates(A, B) | xs:dayTimeDuration |
| A - B | xs:date | xs:yearMonthDuration | op:subtract-yearMonthDuration-from-date(A, B) | xs:date |
| A - B | xs:date | xs:dayTimeDuration | op:subtract-dayTimeDuration-from-date(A, B) | xs:date |
| A - B | xs:time | xs:time | op:subtract-times(A, B) | xs:dayTimeDuration |
| A - B | xs:time | xs:dayTimeDuration | op:subtract-dayTimeDuration-from-time(A, B) | xs:time |
| A - B | xs:dateTime | xs:dateTime | op:subtract-dateTimes(A, B) | xs:dayTimeDuration |
| A - B | xs:dateTime | xs:yearMonthDuration | op:subtract-yearMonthDuration-from-dateTime(A, B) | xs:dateTime |
| A - B | xs:dateTime | xs:dayTimeDuration | op:subtract-dayTimeDuration-from-dateTime(A, B) | xs:dateTime |
| A - B | xs:yearMonthDuration | xs:yearMonthDuration | op:subtract-yearMonthDurations(A, B) | xs:yearMonthDuration |
| A - B | xs:dayTimeDuration | xs:dayTimeDuration | op:subtract-dayTimeDurations(A, B) | xs:dayTimeDuration |
| A * B | xs:numeric | xs:numeric | op:numeric-multiply(A, B) | xs:numeric |
| A * B | xs:yearMonthDuration | xs:numeric | op:multiply-yearMonthDuration(A, B) | xs:yearMonthDuration |
| A * B | xs:numeric | xs:yearMonthDuration | op:multiply-yearMonthDuration(B, A) | xs:yearMonthDuration |
| A * B | xs:dayTimeDuration | xs:numeric | op:multiply-dayTimeDuration(A, B) | xs:dayTimeDuration |
| A * B | xs:numeric | xs:dayTimeDuration | op:multiply-dayTimeDuration(B, A) | xs:dayTimeDuration |
| A idiv B | xs:numeric | xs:numeric | op:numeric-integer-divide(A, B) | xs:integer |
| A div B | xs:numeric | xs:numeric | op:numeric-divide(A, B) | numeric; but xs:decimal if both operands are xs:integer |
| A div B | xs:yearMonthDuration | xs:numeric | op:divide-yearMonthDuration(A, B) | xs:yearMonthDuration |
| A div B | xs:dayTimeDuration | xs:numeric | op:divide-dayTimeDuration(A, B) | xs:dayTimeDuration |
| A div B | xs:yearMonthDuration | xs:yearMonthDuration | op:divide-yearMonthDuration-by-yearMonthDuration(A, B) | xs:decimal |
| A div B | xs:dayTimeDuration | xs:dayTimeDuration | op:divide-dayTimeDuration-by-dayTimeDuration(A, B) | xs:decimal |
| A mod B | xs:numeric | xs:numeric | op:numeric-mod(A, B) | xs:numeric |
Note:
The operator symbol × is a synonym of *, while ÷ is a synonym of div.
If there is no entry in the table for the combination of operator and operands, then a type error is raised [err:XPTY0004].
Errors may also occur during coercion of the operands, or during evaluation of the identified function (for example, an error might result from dividing by zero).
Note:
XQuery 4.0 provides three division operators:
The div and ÷ operators are synonyms, and implement numeric division as well as division of duration values; the semantics are defined in [Functions and Operators 4.0] section 4.2.4 op:numeric-divide
The idiv operator implements integer division; the semantics are defined in [Functions and Operators 4.0] section 4.2.5 op:numeric-integer-divide
Here are some examples of arithmetic expressions:
The first expression below returns the xs:decimal value -1.5, and the second expression returns the xs:integer value -1:
-3 div 2 -3 idiv 2
Subtraction of two date values results in a value of type xs:dayTimeDuration:
$emp/hiredate - $emp/birthdate
This example illustrates the difference between a subtraction operator and a hyphen:
$unit-price - $unit-discount
Unary operators have higher precedence than binary operators (other than !, /, and []), subject of course to the use of parentheses. Therefore, the following two examples have different meanings:
-$bellcost + $whistlecost -($bellcost + $whistlecost)
Note:
Multiple consecutive unary arithmetic operators are permitted (though not useful).
Note:
Negation is not the same as subtraction from zero: if $x is positive zero, then -$x returns negative zero, wheras 0 - $x returns positive zero.
This section describes several ways of constructing strings.
StringTemplate | ::= | "`" (StringTemplateFixedPart | StringTemplateVariablePart)* "`" |
| /* ws: explicit */ | ||
StringTemplateFixedPart | ::= | ((Char - ('{' | '}' | '`')) | "{{" | "}}" | "``")+ |
| /* ws: explicit */ | ||
Char | ::= | [http://www.w3.org/TR/REC-xml#NT-Char]XML |
| /* xgc: xml-version */ | ||
StringTemplateVariablePart | ::= | EnclosedExpr |
EnclosedExpr | ::= | "{" Expr? "}" |
String templates provide an alternative way of constructing strings. For example, the expression `Pi is { round(math:pi(), 4) }` returns the string "Pi is 3.1416".
A string template starts and ends with U+0060 (GRAVE ACCENT, BACKTICK, `) , popularly known as a back-tick. Between the back-ticks is a string consisting of an sequence of fixed parts and variable parts:
A variable part consists of an optional XPath expression enclosed in curly brackets ({}): more specifically, a string conforming to the XPath production Expr?.
Note:
An expression within a variable part may contain an unescaped U+007B (LEFT CURLY BRACKET, {) or U+007D (RIGHT CURLY BRACKET, }) within a StringLiteral or within a comment.
The fact that the expression is optional means that the string contained between the curly brackets may be zero-length, may comprise whitespace only, or may contain XPath comments. The effective value in this case is a zero-length string, which is equivalent to omitting the variable part entirely, together with its curly-bracket delimiters.
A fixed part may contain any characters, except that:
The character U+007B (LEFT CURLY BRACKET, {) must be written as {{.
The character U+007D (RIGHT CURLY BRACKET, }) must be written as }}.
The character U+0060 (GRAVE ACCENT, BACKTICK, `) must be written as ``.
Following the principles of the “longest token” rule, any occurrence of {{ within the fixed part is interpreted as an escaped left curly bracket. This means that the enclosed expression must not start with U+007B (LEFT CURLY BRACKET, {) : if this is required, the two left curly brackets can be separated by whitespace. For example the string template `{{"key":"{ {1:"yes", 0:"no"}?$condition}"}}` evaluates to the string {"key":"yes"} or {"key":"no"} depending on the value of $condition.
By contrast, if the enclosed expression ends with U+007D (RIGHT CURLY BRACKET, }) , this can be immediately followed by the closing U+007D (RIGHT CURLY BRACKET, }) delimiter without intervening whitespace.
The result of evaluating a string template is the string obtained by concatenating the expansions of the fixed and variable parts:
The expansion of a fixed part is obtained by replacing any double curly brackets ({{ or }}) by the corresponding single curly bracket, and replacing doubled back-ticks (``) by a single back-tick.
The expansion of a variable part containing an expression is as follows:
Atomization is applied to the value of the enclosed expression, converting it to a sequence of atomic items.
If the result of atomization is anthe empty sequence, the result is the zero-length string. Otherwise, each atomic item in the atomized sequence is cast into a string.
The individual strings resulting from the previous step are merged into a single string by concatenating them with a single space character between each pair.
The expansion of anthe empty variable part (one that contains no expression) is a zero-length string.
For example:
let $greeting := "Hello", $planet := "Mars"
return `{ $greeting }, { $planet }!`returns "Hello, Mars!".
The expression:
let $long-months := (1, 3, 5, 7, 8, 10, 12)
return `The months with 31 days are: { $long-months }.`returns "The months with 31 days are: 1 3 5 7 8 10 12.".
Note:
The rules for processing an enclosed expression are identical to the rules for attributes in XQuery direct element constructors. These rules differ slightly from the rules in XSLT attribute value templates, where adjacent text nodes are concatenated with no separator, prior to atomization.
Note:
A string template containing no variable parts is effectively just another way of writing a string literal: "Goethe", 'Goethe', and `Goethe` are interchangeable. This means that back-ticks can sometimes be a useful way of delimiting a string that contains both single and double quotes: `He said: "I didn't."`.
It is sometimes useful to use string templates in conjunction with the fn:char function to build strings containing special characters, for example `Chapter{ fn:char("nbsp") }{ $chapNr }`.
Note:
String literals containing an ampersand behave differently between XPath and XQuery: in XPath (unless first expanded by an XML parser) the string literal "Bacon & Eggs" represents a string containing an ampersand, while in XQuery it is an error, because an ampersand is taken as introducing a character reference. This difference does not arise for string templates, since neither XPath nor XQuery recognizes entity or character references in a string template. This means that back-tick delimited strings (such as `Bacon & Eggs`) may be useful in contexts where an XPath expression is required to have the same effect whether it is evaluated using an XPath or an XQuery processor.
In XQuery, the token ``[ is recognized as the start of a string constructor, under the “longest token” rule (see A.3 Lexical structure). This means that the construct ``[1] is not recognized as a StringTemplate followed by a predicate. In the unlikely event that an empty StringTemplate followed by a predicate is wanted, whitespace or parentheses can be used to avoid the tokenization problem.
Comparison expressions allow two values to be compared. XQuery 4.0 provides three kinds of comparison expressions, called value comparisons, general comparisons, and GNode comparisons.
ComparisonExpr | ::= | OtherwiseExpr ((ValueComp | GeneralComp | NodeComp) OtherwiseExpr)? |
OtherwiseExpr | ::= | StringConcatExpr ("otherwise" StringConcatExpr)* |
ValueComp | ::= | "eq" | "ne" | "lt" | "le" | "gt" | "ge" |
GeneralComp | ::= | "=" | "!=" | "<" | "<=" | ">" | ">=" |
NodeComp | ::= | "is" | "is-not" | NodePrecedes | NodeFollows | "precedes-or-is" | "follows-or-is" |
NodePrecedes | ::= | "<<" | "precedes" |
NodeFollows | ::= | ">>" | "follows" |
For a summary of the differences between different ways of comparing atomic items in XQuery 4.0, see H Atomic Comparisons: An Overview.
Changes in 4.0 (next | previous)
The rules for value comparisons when comparing values of different types (for example, decimal and double) have changed to be transitive. A decimal value is no longer converted to double, instead the double is converted to a decimal without loss of precision. This may affect compatibility in edge cases involving comparison of values that are numerically very close. [Issue 986 PR 2218 29 September 2025]
An ordering is now defined for all data types. [Issue 2216 PR 2256 1 December 2025]
The value comparison operators are eq, ne, lt, le, gt, and ge. Value comparisons are used for comparing single atomic items.
The first step in evaluating a value comparison is to evaluate its operands. The order in which the operands are evaluated is implementation-dependent. Each operand is evaluated by applying the following steps, in order:
Atomization is applied to each operand. The result of this operation is called the atomized operand.
If either or both of the atomized operands is anthe empty sequence, the result of the value comparison is anthe empty sequence, and the implementation need not evaluate the other operand or apply the operator. However, an implementation may choose to evaluate the other operand and may raise an error if evaluation fails.
If an atomized operand is a sequence of length greater than one, a type error is raised [err:XPTY0004].
If both operands are instances of xs:numeric, and if either or both of the atomized operands is NaN, then the result is false if the operator is eq, lt, gt, le, or ge, but true if the operator is ne.
Note:
When an operand is NaN, the effect of a value comparison expression differs from the result of the fn:compare function.
The function fn:compare is then called, supplying the two atomized operands as the first two arguments. The collation used by fn:compare is the default collation from the static context, and the implicit timezone used by the function is the implicit timezone from the dynamic context.
Note:
The effect of this rule is that xs:untypedAtomic values (which typically result from atomizing a node) are treated as strings.
If fn:compare raises an error (typically because the two operands belong to different type familiesDM), then the value comparison fails with that error.
The result of the fn:compare function determines the result of the value comparison, according to the following table:
Result of fn:compare | eq | ne | lt | le | gt | ge |
|---|---|---|---|---|---|---|
-1 | false | true | true | true | false | false |
0 | true | false | false | true | false | true |
+1 | false | true | false | false | true | true |
Here are some examples of value comparisons:
The following comparison atomizes the node(s) that are returned by the expression $book/author. The comparison is true only if the result of atomization is the value "Kennedy" as an instance of xs:string or xs:untypedAtomic. If the result of atomization is anthe empty sequence, the result of the comparison is anthe empty sequence. If the result of atomization is a sequence containing more than one value, a type error is raised [err:XPTY0004].
$book1/author eq "Kennedy"
The following comparison is true because atomization converts an array to its member sequence:
[ "Kennedy" ] eq "Kennedy"
The following path expression contains a predicate that selects products whose weight is greater than 100. For any product that does not have a weight subelement, the value of the predicate is the empty sequence, and the product is not selected. This example assumes that weight is a validated element with a numeric type.
//product[weight gt 100]
The following comparisons are true because, in each case, the two constructed nodes have the same value after atomization, even though they have different identities and/or names:
<a>5</a> eq <a>5</a>
<a>5</a> eq <b>5</b>
The following comparison is true if my:hatsize and my:shoesize are both user-defined types that are derived by restriction from a primitive numeric type:
my:hatsize(5) eq my:shoesize(5)
The following comparison is true. The eq operator compares two QNames by performing codepoint-comparisons of their namespace URIs and their local names, ignoring their namespace prefixes.
QName("http://example.com/ns1", "this:color") eq
QName("http://example.com/ns1", "that:color")The following comparison is false. The xs:double value 1.1e0 is converted to type xs:decimal, giving the result 1.100000000000000088817841970012523233890533447265625, which is not equal to the xs:decimal value 1.1.
1.1 eq 1.1e0
Note:
This is incompatible with previous versions, which converted both operands to xs:double before comparing them. This change has been made because there are contexts (such as sorting and grouping) where it is important that comparison results should be transitive, and this was not previously the case.
Changes in 4.0 (next | previous)
Operator is-not is introduced, as a complement to the operator is. [ PR 2130 28 July 2025]
Operators precedes and follows are introduced as synonyms for operators << and >>. [ PR 2130 28 July 2025]
Operators precedes-or-is and follows-or-is are introduced as synonyms for the union of operators << and is and for the union of operators >> and is, respectively. [ PR 2176 22 August 2025]
GNode comparisons are used to compare two GNodes (that is, XNodes or JNodesDM), by their identity or by their document order. The result of a GNode comparison is defined by the following rules:
The operands of a GNode comparison are evaluated in implementation-dependent order.
If either operand is anthe empty sequence, the result of the comparison is anthe empty sequence, and the implementation need not evaluate the other operand or apply the operator. However, an implementation may choose to evaluate the other operand in order to determine whether it raises an error.
Each operand must be either a single GNode or anthe empty sequence; otherwise a type error is raised [err:XPTY0004].
A comparison with the is operator is true if the values of two operands are the same GNode; otherwise it is false. See [XDM 4.0] for the definition of GNode identity.
A comparison with the is-not operator is false if the values of two operands are the same GNode; otherwise it is true. See [XDM 4.0] for the definition of GNode identity.
A comparison with the << or precedes operator returns true if the left operand GNode precedes the right operand GNode in document order; otherwise it returns false.
A comparison with the >> or follows operator returns true if the left operand GNode follows the right operand GNode in document order; otherwise it returns false.
A comparison with the precedes-or-is operator returns true if the left operand GNode precedes the right operand GNode in document order or if the values of two operands are the same GNode; otherwise it returns false.
A comparison with the follows-or-is operator returns true if the left operand GNode follows the right operand GNode in document order or if the values of two operands are the same GNode; otherwise it returns false.
Here are some examples of GNode comparisons:
The following comparison is true only if the left and right sides each evaluate to exactly the same single node:
/books/book[isbn = "1558604820"] is /books/book[call = "QA76.9 C3845"]
The following comparison is false because each constructed node has its own identity:
<a>5</a> is <a>5</a>
The following comparison is true only if the node identified by the left side occurs before the node identified by the right side in document order:
/transactions/purchase[parcel = "28-451"] << /transactions/sale[parcel = "33-870"]
The following comparison is true only if the first integer among the members of an array precedes the first string. This expression compares two JNodes:
let $A := ["Q", 3, "E", "R", "T", 5, "Y"] return $A ? child::type(xs:integer)[1] precedes $A ? child::type(xs:string)[1]
XQuery provides node constructors that can create XML nodes within a query.
Constructors are provided for element, attribute, document, text, comment, and processing instruction nodes. Two kinds of constructors are provided: direct constructors, which use an XML-like notation that can incorporate enclosed expressions, and computed constructors, which use a notation based on enclosed expressions.
The rest of this section contains a conceptual description of the semantics of various kinds of constructor expressions. An XQuery implementation is free to use any implementation technique that produces the same result as the processing steps described here.
An element constructor creates an element node. [Definition: A direct element constructor is a form of element constructor in which the name of the constructed element is a constant.] Direct element constructors are based on standard XML notation. For example, the following expression is a direct element constructor that creates a book element containing an attribute and some nested elements:
<book isbn="isbn-0060229357">
<title>Harold and the Purple Crayon</title>
<author>
<first>Crockett</first>
<last>Johnson</last>
</author>
</book>The element name, written as a lexical QName, is expanded using the constructed element namespace rule.
Note:
The statically known namespaces may be affected by namespace declaration attributes found inside the element constructor.
The namespace prefix of the element name is retained after expansion of the lexical QName, as described in [XDM 4.0]. The resulting expanded QName becomes the node-name property of the constructed element node.
The name used in the end tag must exactly match the name used in the corresponding start tag, including its prefix or absence of a prefix [err:XQST0118].
In a direct element constructor, curly brackets (U+007B (LEFT CURLY BRACKET, {) and U+007D (RIGHT CURLY BRACKET, }) ) delimit enclosed expressions, distinguishing them from literal text. Enclosed expressions are evaluated and replaced by their value, as illustrated by the following example:
<example>
<p> Here is a query. </p>
<eg> $b/title </eg>
<p> Here is the result of the query. </p>
<eg>{ $b/title }</eg>
</example>The above query might generate the following result (whitespace has been added for readability to this result and other result examples in this document):
<example> <p> Here is a query. </p> <eg> $b/title </eg> <p> Here is the result of the query. </p> <eg><title>Harold and the Purple Crayon</title></eg> </example>
Since XQuery uses U+007B (LEFT CURLY BRACKET, {) and U+007D (RIGHT CURLY BRACKET, }) to delimit enclosed expressions, some convention is needed to denote a curly bracket used as an ordinary character. For this purpose, a pair of identical curly bracket characters within the content of an element or attribute are interpreted by XQuery as a single curly bracket character (that is, the pair "{{" represents the character U+007B (LEFT CURLY BRACKET, {) and the pair "}}" represents the character U+007D (RIGHT CURLY BRACKET, }) .) Alternatively, the character references{ and } can be used to denote curly bracket characters. A single U+007B (LEFT CURLY BRACKET, {) is interpreted as the beginning delimiter for an enclosed expression. A single U+007D (RIGHT CURLY BRACKET, }) without a matching left curly bracket is treated as a static error [err:XPST0003].
Within an enclosed expression, the handling of expressions that start with U+007B (LEFT CURLY BRACKET, {) or that end with U+007D (RIGHT CURLY BRACKET, }) is the same as for 4.9.2 String Templates.
The result of an element constructor is a new element node, with its own node identity. All the attribute and descendant nodes of the new element node are also new nodes with their own identities, even if they are copies of existing nodes.
The start tag of a direct element constructor may contain one or more attributes. As in XML, each attribute is specified by a name and a value. In a direct element constructor, the name of each attribute is specified by a constant lexical QName, and the value of the attribute is specified by a string of characters enclosed in single or double quotes. As in the main content of the element constructor, an attribute value may contain enclosed expressions, which are evaluated and replaced by their value during processing of the element constructor.
Each attribute in a direct element constructor creates a new attribute node, with its own node identity, whose parent is the constructed element node. However, note that namespace declaration attributes (see 4.12.1.2 Namespace Declaration Attributes) do not create attribute nodes.
The attribute name, written as a lexical QName, is expanded using the no-namespace rule.
Note:
The statically known namespaces used in resolving an attribute name may be affected by namespace declaration attributes that are found inside the same element constructor.
The namespace prefix of the attribute name is retained after expansion of the lexical QName, as described in [XDM 4.0]. The resulting expanded QName becomes the node-name property of the constructed attribute node.
If the attributes in a direct element constructor do not have distinct expanded QNames as their respective node-name properties, a static error is raised [err:XQST0040].
Conceptually, an attribute (other than a namespace declaration attribute) in a direct element constructor is processed by the following steps:
Each consecutive sequence of literal characters in the attribute content is processed as a string literal containing those characters, with the following exceptions:
Each occurrence of two consecutive { characters is replaced by a single { character.
Each occurrence of two consecutive } characters is replaced by a single } character.
Each occurrence of EscapeQuot is replaced by a single " character.
Each occurrence of EscapeApos is replaced by a single ' character.
Within an enclosed expression, the handling of expressions that start with U+007B (LEFT CURLY BRACKET, {) or that end with U+007D (RIGHT CURLY BRACKET, }) is the same as for 4.9.2 String Templates.
Attribute value normalization is then applied to normalize whitespace and expand character references and predefined entity references. The rules for attribute value normalization are the rules from Section 3.3.3 of [XML 1.0] or Section 3.3.3 of [XML 1.1] (it is implementation-defined which version is used). The rules are applied as though the type of the attribute were CDATA (leading and trailing whitespace characters are not stripped.)
Each enclosed expression is converted to a string as follows:
Atomization is applied to the value of the enclosed expression, converting it to a sequence of atomic items.
If the result of atomization is anthe empty sequence, the result is the zero-length string. Otherwise, each atomic item in the atomized sequence is cast into a string.
The individual strings resulting from the previous step are merged into a single string by concatenating them with a single space character between each pair.
Adjacent strings resulting from the above steps are concatenated with no intervening blanks. The resulting string becomes the string-value property of the attribute node. The attribute node is given a type annotation of xs:untypedAtomic (this type annotation may change if the parent element is validated). The typed-value property of the attribute node is the same as its string-value, as an instance of xs:untypedAtomic.
The parent property of the attribute node is set to the element node constructed by the direct element constructor that contains this attribute.
If the attribute name is xml:id, then xml:id processing is performed as defined in [XML ID]. This ensures that the attribute has the type xs:ID and that its value is properly normalized. If an error is encountered during xml:id processing, an implementation may raise a dynamic error [err:XQDY0091].
If the attribute name is xml:id, the is-id property of the resulting attribute node is set to true; otherwise the is-id property is set to false. The is-idrefs property of the attribute node is unconditionally set to false.
Example:
<shoe size="7"/>
The string value of the size attribute is "7".
Example:
<shoe size="{ 7 }"/>The string value of the size attribute is "7".
Example:
<shoe size="{ () }"/>The string value of the size attribute is the zero-length string.
Example:
<chapter ref="[ { 1, 5 to 7, 9 } ]"/>The string value of the ref attribute is "[1 5 6 7 9]".
Example:
<shoe size="As big as { $hat/@size }"/>The string value of the size attribute is the string "As big as ", concatenated with the string value of the node denoted by the expression $hat/@size.
ComputedConstructor | ::= | CompDocConstructor |
CompDocConstructor | ::= | "document" EnclosedExpr |
CompElemConstructor | ::= | "element" CompNodeNameEnclosedContentExpr |
CompAttrConstructor | ::= | "attribute" CompNodeNameEnclosedExpr |
CompNamespaceConstructor | ::= | "namespace" CompNodeNCNameEnclosedExpr |
CompTextConstructor | ::= | "text" EnclosedExpr |
CompCommentConstructor | ::= | "comment" EnclosedExpr |
CompPIConstructor | ::= | "processing-instruction" CompNodeNCNameEnclosedExpr |
An alternative way to create nodes is by using a computed constructor. A computed constructor begins with a keyword that identifies the type of node to be created: element, attribute, document, text, processing-instruction, comment, or namespace.
For those kinds of nodes that have names (element, attribute, processing instruction, and namespace nodes), the keyword that specifies the node kind is followed by the name of the node to be created. This name may be specified either as an EQName or as an expression enclosed in braces. [Definition: When an expression is used to specify the name of a constructed node, that expression is called the name expression of the constructor.]
The following example illustrates the use of computed element and attribute constructors in a simple case where the names of the constructed nodes are constants. This example generates exactly the same result as the first example in 4.12.1 Direct Element Constructors:
element book {
attribute isbn { "isbn-0060229357" },
element title { "Harold and the Purple Crayon" },
element author {
element first { "Crockett" },
element last { "Johnson" }
}
}Note:
XQuery 4.0 allows the node name to be written in quotation marks (for example, element "book" {}, and at the same time it disallows the use of a defined set of language keywords without quotes: for example element div {} was allowed in XQuery 3.1 but must now be written element #div {} or element { "div" } {}. The reason for this incompatible change is that allowing map constructors to omit the map keyword would otherwise create an ambiguity: consider for example the expression element otherwise {}.
Because the list of reserved keywords may be extended in future versions of this specification, the safest strategy is to always use the QNameLiteral syntax (for example element #div). To avoid any dependency on the default namespace context, the form element Q{}div might also be used.
To write code that is portable between XQuery 3.1 and XQuery 4.0, the best advice is to use either the form element { "div" } or the form element Q{}div.
CompElemConstructor | ::= | "element" CompNodeNameEnclosedContentExpr |
CompNodeName | ::= | QNameLiteral | UnreservedName | ("{" Expr "}") |
QNameLiteral | ::= | "#" EQName |
UnreservedName | ::= | EQName |
| /* xgc: unreserved-name */ | ||
EQName | ::= | QName | URIQualifiedName |
Expr | ::= | (ExprSingle ++ ",") |
EnclosedContentExpr | ::= | EnclosedExpr |
EnclosedExpr | ::= | "{" Expr? "}" |
[Definition: A computed element constructor creates an element node, allowing both the name and the content of the node to be computed.]
The element name is determined by the CompNodeName, which may be provided in a number of ways:
As a QName literal, for example:
element #table {}element #html:table {}element #Q{}table {}element #Q{http://http://www.w3.org/1999/xhtml}table {}element #Q{http://http://www.w3.org/1999/xhtml}html:table {}
A QName literal written as an unprefixed lexical QName (the first form above) is resolved using the constructed element namespace rule. This differs from the normal rules for evaluating a QName literal as an atomic item of type xs:QName.
Note that the third and fourth examples (#Q{}table and #Q{http://http://www.w3.org/1999/xhtml}table) will result in the name of the constructed element having no prefix, which may in turn trigger the generation of a default namespace declaration.
As a simple EQName, for example:
element table {}element html:table {}element Q{}table {}element Q{http://http://www.w3.org/1999/xhtml}table {}element Q{http://http://www.w3.org/1999/xhtml}html:table {}
In XQuery 4.0 the first form (using an unprefixed lexical QName) is allowed only if the element name is not a reserved keyword (such as div or value): see unreserved-name. In all other cases, the effect is exactly the same as when a leading # is added to turn the EQName into a QName literal.
This syntax is retained for compatibility, but is deprecated.
As an expression in curly brackets. This is processed as follows:
Atomization is applied to the value of the name expression. If the result of atomization is not a single atomic item of type xs:QName, xs:string, or xs:untypedAtomic, a type error is raised [err:XPTY0004].
If the atomized value of the name expression is of type xs:QName, that expanded QName is used as the node-name property of the constructed element, retaining the prefix part of the QName.
If the atomized value of the name expression is of type xs:string or xs:untypedAtomic, that value is converted to an expanded QNameas follows:
Leading and trailing whitespace is removed.
If the value is a lexical QName, it is expanded using the constructed element namespace rule.
If the value is in the form of a URIQualifiedName (Q{uri}local or Q{uri}prefix:local), it is converted to an expanded QName with the supplied namespace URI and local name, and with the specified prefix if present.
Note:
This was under-specified in XQuery 3.1.
If conversion of the atomized name expression to an expanded QName is not successful, a dynamic error is raised [err:XQDY0074].
The resulting expanded QName is used as the node-name property of the constructed element, retaining the prefix part of the QName (or its absence).
An error is raised [err:XQDY0096] if the node-name of the constructed element node has any of the following properties:
Its namespace prefix is xmlns.
Its namespace URI is http://www.w3.org/2000/xmlns/.
Its namespace prefix is xml and its namespace URI is not http://www.w3.org/XML/1998/namespace.
Its namespace prefix is other than xml and its namespace URI is http://www.w3.org/XML/1998/namespace.
The above error may be raised as a static error if the element name is computed statically; in other cases it must be raised as a dynamic error.
The content expression of a computed element constructor (if present) is processed in exactly the same way as an enclosed expression in the content of a direct element constructor, as described in Step 1e of 4.12.1.3 Content. The result of processing the content expression is a sequence of nodes called the content sequence. If the content expression is absent, the content sequence is anthe empty sequence.
Processing of the computed element constructor proceeds as follows:
If the content sequence contains a document node, the document node is replaced in the content sequence by its children.
Adjacent text nodes in the content sequence are merged into a single text node by concatenating their contents, with no intervening blanks. After concatenation, any text node whose content is a zero-length string is deleted from the content sequence.
If the content sequence contains an attribute node or a namespace node following a node that is not an attribute node or a namespace node, a type error is raised [err:XQTY0024].
The properties of the newly constructed element node are determined as follows:
node-name is the expanded QName resulting from processing the specified CompNodeName, as described above.
parent is empty.
attributes consist of all the attribute nodes in the content sequence, in implementation-dependent order. Note that the parent property of each of these attribute nodes has been set to the newly constructed element node. If two or more attributes have the same node-name, a dynamic error is raised [err:XQDY0025]. If an attribute named xml:space has a value other than preserve or default, a dynamic error may be raised [err:XQDY0092].
children consist of all the element, text, comment, and processing instruction nodes in the content sequence. Note that the parent property of each of these nodes has been set to the newly constructed element node.
base-uri is set to the following value:
If the constructed node has an attribute named xml:base, then the value of this attribute, resolved (if it is relative) against the Executable Base URI, as described in 2.6.7 Resolving a Relative URI Reference.
Otherwise, the Executable Base URI.
The in-scope namespaces are computed as described in 4.12.4 In-scope Namespaces of a Constructed Element.
The nilled property is false.
The string-value property is equal to the concatenated contents of the text-node descendants in document order.
The typed-value property is equal to the string-value property, as an instance of xs:untypedAtomic.
If construction mode in the static context is strip, the type-name property is xs:untyped. On the other hand, if construction mode is preserve, the type-name property is xs:anyType.
The is-id and is-idrefs properties are set to false.
A computed element constructor might be used to make a modified copy of an existing element. For example, if the variable $e is bound to an element with numeric content, the following constructor might be used to create a new element with the same name and attributes as $e and with numeric content equal to twice the value of $e:
element { node-name($e) } { $e/@*, 2 * data($e) }In this example, if $e is bound by the expression let $e := <length units="inches">{ 5 }</length>, then the result of the example expression is the element <length units="inches">10</length>.
Note:
The static type of the expression fn:node-name($e) is xs:QName?, denoting zero or one QName. The example can be successfully evaluated as written provided that $e is bound to exactly one element node with numeric content.
One important purpose of computed constructors is to allow the name of a node to be computed. We will illustrate this feature by an expression that translates the name of an element from one language to another. Suppose that the variable $dict is bound to a dictionary element containing a sequence of entry elements, each of which encodes translations for a specific word. Here is an example entry that encodes the German and Italian variants of the word “address”:
<entry word="address"> <variant xml:lang="de">Adresse</variant> <variant xml:lang="it">indirizzo</variant> </entry>
Suppose further that the variable $e is bound to the following element:
<address>123 Roosevelt Ave. Flushing, NY 11368</address>
Then the following expression generates a new element in which the name of $e has been translated into Italian and the content of $e (including its attributes, if any) has been preserved. The first enclosed expression after the element keyword generates the name of the element, and the second enclosed expression generates the content and attributes:
element {
$dict/entry[@word = name($e)]/variant[@xml:lang = "it"]
} {
$e/@*, $e/node()
}The result of this expression is as follows:
<indirizzo>123 Roosevelt Ave. Flushing, NY 11368</indirizzo>
CompAttrConstructor | ::= | "attribute" CompNodeNameEnclosedExpr |
CompNodeName | ::= | QNameLiteral | UnreservedName | ("{" Expr "}") |
QNameLiteral | ::= | "#" EQName |
UnreservedName | ::= | EQName |
| /* xgc: unreserved-name */ | ||
EQName | ::= | QName | URIQualifiedName |
Expr | ::= | (ExprSingle ++ ",") |
EnclosedExpr | ::= | "{" Expr? "}" |
A computed attribute constructor creates a new attribute node, with its own node identity.
Attributes have no default namespace. The rules that expand attribute names create an implementation-dependent prefix if an attribute name has a namespace URI but no prefix is provided.
The attribute name may be provided in a number of ways:
As a QName literal, for example:
attribute #width {}attribute #xsi:type {}attribute #Q{}width {}attribute #Q{http://www.w3.org/2001/XMLSchema-instance}xsi:type {}attribute #Q{http://www.w3.org/2001/XMLSchema-instance}type {}
A QName literal written as an unprefixed lexical QName (the first form above) is resolved using the no-namespace ruleno-namespace rule.
Note that the last example (#Q{http://www.w3.org/2001/XMLSchema-instance}type) will result in the name of the constructed attribute having a system-generated prefix.
As a simple EQName, for example:
attribute width {}attribute xsi:type {}attribute Q{}width {}attribute Q{http://www.w3.org/2001/XMLSchema-instance}xsi:type {}attribute Q{http://www.w3.org/2001/XMLSchema-instance}type {}
In XQuery 4.0 the first form (using an unprefixed lexical QName) is allowed only if the attribute name is not a reserved keyword (such as div or value): see unreserved-name. In all other cases, the effect is exactly the same as when a leading # is added to turn the EQName into a QName literal.
This syntax is retained for compatibility, but is deprecated.
As an expression in curly brackets. This is processed as follows:
Atomization is applied to the result of the name expression. If the result of atomization is not a single atomic item of type xs:QName, xs:string, or xs:untypedAtomic, a type error is raised [err:XPTY0004].
If the atomized value of the name expression is of type xs:QName:
If the expanded QName returned by the atomized name expression has a namespace URI but has no prefix, it is given an implementation-dependent prefix.
The resulting expanded QName (including its prefix) is used as the node-name property of the constructed attribute node.
If the atomized value of the name expression is of type xs:string or xs:untypedAtomic, that value is converted to an expanded QNameas follows:
Leading and trailing whitespace is removed.
If the value is a lexical QName, it is expanded using the no-namespace rule.
If the value is in the form of a URIQualifiedName (Q{uri}local or Q{uri}prefix:local), it is converted to an expanded QName with the supplied namespace URI, local name, and prefix, or with an implementation dependent prefix if none is supplied.
If conversion of the atomized name expression to an expanded QName is not successful, a dynamic error is raised [err:XQDY0074].
Note:
This was under-specified in XQuery 3.1.
The resulting expanded QName (including its prefix) is used as the node-name property of the constructed attribute node. If expansion of the QName is not successful, a static error is raised [err:XPST0081].
If the keyword attribute is followed by a name expression, the name expression is processed as follows:
A dynamic error is raised [err:XQDY0044] if the node-name of the constructed attribute node has any of the following properties:
Its namespace prefix is xmlns.
It has no namespace prefix and its local name is xmlns.
Its namespace URI is http://www.w3.org/2000/xmlns/.
Its namespace prefix is xml and its namespace URI is not http://www.w3.org/XML/1998/namespace.
Its namespace prefix is other than xml and its namespace URI is http://www.w3.org/XML/1998/namespace.
The content expression of a computed attribute constructor is processed as follows:
Atomization is applied to the result of the content expression, converting it to a sequence of atomic items. (If the content expression is absent, the result of this step is anthe empty sequence.)
If the result of atomization is anthe empty sequence, the value of the attribute is the zero-length string. Otherwise, each atomic item in the atomized sequence is cast into a string.
The individual strings resulting from the previous step are merged into a single string by concatenating them with a single space character between each pair. The resulting string becomes the string-value property of the new attribute node. The type annotation (type-name property) of the new attribute node is xs:untypedAtomic. The typed-value property of the attribute node is the same as its string-value, as an instance of xs:untypedAtomic.
The parent property of the attribute node is set to empty.
If the attribute name is xml:id, then xml:id processing is performed as defined in [XML ID]. This ensures that the attribute node has the type xs:ID and that its value is properly normalized. If an error is encountered during xml:id processing, an implementation may raise a dynamic error [err:XQDY0091].
If the attribute name is xml:id, the is-id property of the resulting attribute node is set to true; otherwise the is-id property is set to false. The is-idrefs property of the attribute node is unconditionally set to false.
If the attribute name is xml:space and the attribute value is other than preserve or default, a dynamic error may be raised [err:XQDY0092].
Example:
attribute size { 4 + 3 }The string value of the size attribute is "7" and its type is xs:untypedAtomic.
Example:
attribute {
if ($sex = "M") then "husband" else "wife"
} {
<a>Hello</a>, 1 to 3, <b>Goodbye</b>
}The name of the constructed attribute is either husband or wife. Its string value is "Hello 1 2 3 Goodbye".
CompTextConstructor | ::= | "text" EnclosedExpr |
EnclosedExpr | ::= | "{" Expr? "}" |
All text node constructors are computed constructors. The result of a text node constructor is a new text node, with its own node identity.
The content expression of a text node constructor is processed as follows:
Atomization is applied to the value of the content expression, converting it to a sequence of atomic items.
If the result of atomization is anthe empty sequence, no text node is constructed. Otherwise, each atomic item in the atomized sequence is cast into a string.
The individual strings resulting from the previous step are merged into a single string by concatenating them with a single space character between each pair. The resulting string becomes the content property of the constructed text node.
The parent property of the constructed text node is set to empty.
Note:
It is possible for a text node constructor to construct a text node containing a zero-length string. However, if used in the content of a constructed element or document node, such a text node will be deleted or merged with another text node.
The following example illustrates a text node constructor:
text { "Hello" }CompPIConstructor | ::= | "processing-instruction" CompNodeNCNameEnclosedExpr |
CompNodeNCName | ::= | MarkedNCName | UnreservedNCName | ("{" Expr "}") |
MarkedNCName | ::= | "#" NCName |
UnreservedNCName | ::= | NCName |
| /* xgc: unreserved-name */ | ||
Expr | ::= | (ExprSingle ++ ",") |
EnclosedExpr | ::= | "{" Expr? "}" |
A computed processing instruction constructor (CompPIConstructor) constructs a new processing instruction node with its own node identity.
The name of a processing instruction node is always an NCName, and may be provided in a number of ways:
As an NCName with a preceding # sign, for example processing-instruction #xref {}.
As a simple NCName without the preceding #, for example processing-instruction xref {}. This form is allowed only if the name is not a reserved keyword: see unreserved-name.
As an expression in curly braces. This is processed as follows:
Atomization is applied to the value of the name expression. If the result of atomization is not a single atomic item of type xs:NCName, xs:string, or xs:untypedAtomic, a type error is raised [err:XPTY0004].
If the atomized value of the name expression is of type xs:string or xs:untypedAtomic, that value is cast to the type xs:NCName. If the value cannot be cast to xs:NCName, a dynamic error is raised [err:XQDY0041].
The resulting NCName is then used as the target property of the newly constructed processing instruction node. However, a dynamic error is raised if the NCName is equal to "XML" (in any combination of upper and lower case) [err:XQDY0064].
The content expression of a computed processing instruction constructor is processed as follows:
Atomization is applied to the value of the content expression, converting it to a sequence of atomic items. (If the content expression is absent, the result of this step is anthe empty sequence.)
If the result of atomization is anthe empty sequence, it is replaced by a zero-length string. Otherwise, each atomic item in the atomized sequence is cast into a string. If any of the resulting strings contains the string "?>", a dynamic error [err:XQDY0026] is raised.
The individual strings resulting from the previous step are merged into a single string by concatenating them with a single space character between each pair. Leading whitespace is removed from the resulting string. The resulting string then becomes the content property of the constructed processing instruction node.
The remaining properties of the new processing instruction node are determined as follows:
The parent property is empty.
The base-uri property is empty.
The following example illustrates a computed processing instruction constructor:
let $target := "audio-output",
return processing-instruction { $target } { "beep" }The processing instruction node constructed by this example might be serialized as follows:
<?audio-output beep?>
CompCommentConstructor | ::= | "comment" EnclosedExpr |
EnclosedExpr | ::= | "{" Expr? "}" |
A computed comment constructor (CompCommentConstructor) constructs a new comment node with its own node identity. The content expression of a computed comment constructor is processed as follows:
Atomization is applied to the value of the content expression, converting it to a sequence of atomic items.
If the result of atomization is anthe empty sequence, it is replaced by a zero-length string. Otherwise, each atomic item in the atomized sequence is cast into a string.
The individual strings resulting from the previous step are merged into a single string by concatenating them with a single space character between each pair. The resulting string becomes the content property of the constructed comment node.
It is a dynamic error [err:XQDY0072] if the result of the content expression of a computed comment constructor contains two adjacent hyphens or ends with a hyphen.
The parent property of the constructed comment node is set to empty.
The following example illustrates a computed comment constructor:
let $homebase := "Houston"
return comment { concat($homebase, ", we have a problem.") }The comment node constructed by this example might be serialized as follows:
<!--Houston, we have a problem.-->
CompNamespaceConstructor | ::= | "namespace" CompNodeNCNameEnclosedExpr |
CompNodeNCName | ::= | MarkedNCName | UnreservedNCName | ("{" Expr "}") |
MarkedNCName | ::= | "#" NCName |
UnreservedNCName | ::= | NCName |
| /* xgc: unreserved-name */ | ||
Expr | ::= | (ExprSingle ++ ",") |
EnclosedExpr | ::= | "{" Expr? "}" |
A computed namespace constructor creates a new namespace node, with its own node identity. The parent of the newly created namespace node is absent.
The name of a namespace node is always an NCName, and represents the namespace prefix.
The string value of a namespace node should be a URI, and represents the namespace URI.
The namespace prefix may be provided in a number of ways:
As an NCName with a preceding # sign, for example namespace #xlink { "http://www.w3.org/1999/xlink" }.
As a simple NCName with no preceding # sign, for example namespace xlink { "http://www.w3.org/1999/xlink" }. This form is allowed only if the namespace prefix is not a reserved keyword: see unreserved-name.
As an expression in curly braces. This is processed as follows:
Atomization is applied to the result of the enclosed expression.
If the result of atomization is anthe empty sequence or a single atomic item of type xs:string or xs:untypedAtomic, then the following rules are applied in order:
If the result is castable to xs:NCName, then it is used as the local name of the newly constructed namespace node. (The local name of a namespace node represents the prefix part of the namespace binding.)
If the result is the empty sequence or a zero-length xs:string or xs:untypedAtomic item, the new namespace node has no name (such a namespace node represents a binding for the default namespace).
Otherwise, a dynamic error is raised [err:XQDY0074].
If the result of atomization is not anthe empty sequence or a single atomic item of type xs:string or xs:untypedAtomic, a type error is raised [err:XPTY0004].
The content expression is evaluated, and the result is cast to xs:anyURI to create the URI property for the newly created node. An implementation may raise a dynamic error [err:XQDY0074] if the URIExpr of a computed namespace constructor is not a valid instance of xs:anyURI.
An error [err:XQDY0101] is raised if a computed namespace constructor attempts to do any of the following:
Bind the prefix xml to some namespace URI other than http://www.w3.org/XML/1998/namespace.
Bind a prefix other than xml to the namespace URI http://www.w3.org/XML/1998/namespace.
Bind the prefix xmlns to any namespace URI.
Bind a prefix to the namespace URI http://www.w3.org/2000/xmlns/.
Bind any prefix (including the empty prefix) to a zero-length namespace URI.
By itself, a computed namespace constructor has no effect on the in-scope namespaces of any element, but if an element constructor’s content sequence contains a namespace node, the namespace binding it represents is added to that element’s in-scope namespaces.
A computed namespace constructor has no effect on the statically known namespaces in the static context.
Note:
The newly created namespace node has all properties defined for a namespace node in the data model, but its parent is always absent. As defined in the data model, the name of the node is the prefix, the string value of the node is the URI. Since the nodes are parentless, their relative order is implementation dependent.
Examples:
A computed namespace constructor with a prefix:
namespace a { "http://a.example.com" }A computed namespace constructor with a prefix expression:
namespace { "a" } { "http://a.example.com" }A computed namespace constructor with anthe empty prefix:
namespace "" { "http://a.example.com" }Computed namespace constructors are generally used to add to the in-scope namespaces of elements created with element constructors:
<age xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> {
namespace xs { "http://www.w3.org/2001/XMLSchema" },
attribute xsi:type { "xs:integer" },
23
}</age>In the above example, note that the xsinamespace binding is created for the element because it is used in an attribute name. The attribute’s content is simply character data, and has no effect on namespace bindings. The computed namespace constructor ensures that the xs binding is created.
Computed namespace constructors have no effect on the statically known namespaces. If the prefix a is not already defined in the statically known namespaces, the following expression results in a static error [err:XPST0081].
<a:form>{
namespace a { "http://a.example.com" }
}</a:form>XQuery provides a versatile expression called a FLWOR expression that may contain multiple clauses. The FLWOR expression can be used for many purposes, including iterating over sequences, joining multiple documents, and performing grouping and aggregation. The name FLWOR, pronounced "flower", is suggested by the keywords for, let, where, order by, and return, which introduce some of the clauses used in FLWOR expressions (but this is not a complete list of such clauses.)
The overall syntax of a FLWOR expression is shown here, and relevant parts of the syntax are expanded in subsequent sections.
FLWORExpr | ::= | InitialClauseIntermediateClause* ReturnClause |
InitialClause | ::= | ForClause | LetClause | WindowClause |
ForClause | ::= | "for" (ForBinding ++ ",") |
LetClause | ::= | "let" (LetBinding ++ ",") |
WindowClause | ::= | "for" (TumblingWindowClause | SlidingWindowClause) |
IntermediateClause | ::= | InitialClause | WhereClause | WhileClause | GroupByClause | OrderByClause | CountClause |
WhereClause | ::= | "where" ExprSingle |
WhileClause | ::= | "while" ExprSingle |
GroupByClause | ::= | "group" "by" (GroupingSpec ++ ",") |
OrderByClause | ::= | "stable"? "order" "by" (OrderSpec ++ ",") |
CountClause | ::= | "count" VarName |
ReturnClause | ::= | "return" ExprSingle |
The semantics of FLWOR expressions are based on a concept called a tuple stream. [Definition: A tuple stream is an ordered sequence of zero or more tuples.] [Definition: A tuple is a set of zero or more named variables, each of which is bound to a value that is an XDM instance.] Each tuple stream is homogeneous in the sense that all its tuples contain variables with the same names and the same static types. The following example illustrates a tuple stream consisting of four tuples, each containing three variables named $x, $y, and $z:
($x = 1003, $y = "Fred", $z = <age>21</age>) ($x = 1017, $y = "Mary", $z = <age>35</age>) ($x = 1020, $y = "Bill", $z = <age>18</age>) ($x = 1024, $y = "John", $z = <age>29</age>)
Note:
In this section, tuple streams are represented as shown in the above example. Each tuple is on a separate line and is enclosed in parentheses, and the variable bindings inside each tuple are separated by commas. This notation does not represent XQuery syntax, but is simply a representation of a tuple stream for the purpose of defining the semantics of FLWOR expressions.
Tuples and tuple streams are not part of the data model. They exist only as conceptual intermediate results during the processing of a FLWOR expression.
Conceptually, the first clause generates a tuple stream. Each clause between the first clause and the return clause takes the tuple stream generated by the previous clause as input and generates a (possibly different) tuple stream as output. The return clause takes a tuple stream as input and, for each tuple in this tuple stream, generates an XDM instance; the final result of the FLWOR expression is the ordered concatenation of these XDM instances.
The initial clause in a FLWOR expression may be a for, let, or window clause. Intermediate clauses may be for, let, window, count, where, group by, or order by clauses. These intermediate clauses may be repeated as many times as desired, in any order. The final clause of the FLWOR expression must be a return clause. The semantics of the various clauses are described in the following sections.
Changes in 4.0 (next | previous)
A for member clause is added to FLWOR expressions to allow iteration over an array. [Issue 49 PR 344 10 February 2023]
A for key/value clause is added to FLWOR expressions to allow iteration over a map. [Issue 31 PR 1249 1 June 2024]
The value bound to a variable in a for clause is now converted to the declared type by applying the coercion rules. [Issue 189 PR 820 8 November 2023]
ForClause | ::= | "for" (ForBinding ++ ",") |
ForBinding | ::= | ForItemBinding | ForMemberBinding | ForEntryBinding |
ForItemBinding | ::= | VarNameAndTypeAllowingEmpty? PositionalVar? "in" ExprSingle |
VarNameAndType | ::= | "$" EQNameTypeDeclaration? |
EQName | ::= | QName | URIQualifiedName |
TypeDeclaration | ::= | "as" SequenceType |
SequenceType | ::= | ("empty-sequence" "(" ")") |
AllowingEmpty | ::= | "allowing" "empty" |
PositionalVar | ::= | "at" VarName |
VarName | ::= | "$" EQName |
ExprSingle | ::= | FLWORExpr |
ForMemberBinding | ::= | "member" VarNameAndTypePositionalVar? "in" ExprSingle |
ForEntryBinding | ::= | ((ForEntryKeyBindingForEntryValueBinding?) | ForEntryValueBinding) PositionalVar? "in" ExprSingle |
ForEntryKeyBinding | ::= | "key" VarNameAndType |
ForEntryValueBinding | ::= | "value" VarNameAndType |
A for clause is used for iteration. Each variable in a for clause iterates over a sequence, an array, or a map.
The expression following the keyword in is evaluated; we refer to the resulting sequence, array, or map generically as the binding collection, and to its items, members, or entries as the components of the collection.
When a ForItemBinding is used (that is, when none of the keywords member, key, or value is used), the range variable is bound in turn to each item in the binding collection, which is treated as a sequence of items.
When a ForMemberBinding is used (that is, when the keyword member is used), the range variable is bound in turn to each member of the array.
In this case the corresponding ExprSingle must evaluate to a single array, otherwise a type error is raised [err:XPTY0141]. However, the coercion rules also allow a JNode whose ·content· is an array to be supplied.
When a ForEntryBinding is used (that is, when either or both of the keywords key and value are used), the key range variable (if present) is bound in turn to each key in the map (in entry orderDM), and the value range variable (if present) is bound to the corresponding value.
In this case the corresponding ExprSingle must evaluate to a single map, otherwise a type error is raised [err:XPTY0141]. However, the coercion rules also allow a JNode whose ·content· is a map to be supplied.
If both the key and value variables are declared, their expanded QNames must be distinct [err:XQST0089].
If a for clause contains multiple bindings separated by commas it is semantically equivalent to multiple for clauses, each containing one of the bindings in the original for clause.
Example:
The clause
for $x in $expr1, $y in $expr2
is semantically equivalent to:
for $x in $expr1 for $y in $expr2
The clause
for member $x in $expr1, member $y in $expr2
is semantically equivalent to:
for member $x in $expr1 for member $y in $expr2
In the remainder of this section, we define the semantics of a for clause containing a single variable and an associated expression (following the keyword in) whose value is the binding collection for that variable.
If a single-variable for clause is the initial clause in a FLWOR expression, it iterates over its binding collection, binding the variable(s) to each component in turn. The resulting sequence of variable bindings becomes the initial tuple stream that serves as input to the next clause of the FLWOR expression. The order of tuples in the tuple stream preserves the order of the binding collection.
If the binding collection is empty, the output tuple stream depends on whether allowing empty is specified. If allowing empty is specified, the output tuple stream consists of one tuple in which the variable is bound to anthe empty sequence. This option is not available when the keywords member, key, or value are used. If allowing empty is not specified, the output tuple stream consists of zero tuples.
The following examples illustrates tuple streams that are generated by initial for clauses:
Initial clause:
for $x in (100, 200, 300)
or (equivalently):
for $x allowing empty in (100, 200, 300)
Output tuple stream:
($x = 100) ($x = 200) ($x = 300)
Initial clause:
for $x in ()
Output tuple stream contains no tuples.
Initial clause:
for $x allowing empty in ()
Output tuple stream:
($x = ())
Initial clause:
for member $x in [ 1, 2, (5 to 10) ]
Output tuple stream:
($x = (1)) ($x = (2)) ($x = (5, 6, 7, 8, 9, 10)
Initial clause:
for member $x in []
Output tuple stream contains no tuples.
Initial clause:
for key $k value $v in { 'x': 1, 'y': 2 }Output tuple stream:
($k = 'x', $v = 1) ($k = 'y', $v = 2)
[Definition: A positional variable is a variable that is preceded by the keyword at.] A positional variable may be associated with the range variable(s) that are bound in a for clause. In this case, as the main range variable(s) iterate over the components of its binding collection, the positional variable iterates over the integers that represent the ordinal numbers of these component in the binding collection, starting with one. Each tuple in the output tuple stream contains bindings for both the main variable and the positional variable. If the binding collection is empty and allowing empty is specified, the positional variable in the output tuple is bound to the integer zero. Positional variables have the implied type xs:integer.
The expanded QName of a positional variable must be distinct from the expanded QName of the main variable with which it is associated [err:XQST0089].
The following examples illustrate how a positional variable would have affected the results of the previous examples that generated tuples:
Initial clause:
for $x at $i in (100, 200, 300)
Output tuple stream:
($x = 100, $i = 1) ($x = 200, $i = 2) ($x = 300, $i = 3)
Initial clause:
for $x at $i in [1 to 3, 11 to 13, 21 to 23
Output tuple stream:
($x = (1, 2, 3), $i = 1) ($x = (11, 12, 13), $i = 2) ($x = (21, 22, 23), $i = 3)
Initial clause:
for $x allowing empty at $i in ()
Output tuple stream:
($x = (), $i = 0)
If a single-variable for clause is an intermediate clause in a FLWOR expression, its binding collection is evaluated for each input tuple, given the bindings in that input tuple. Each input tuple generates zero or more tuples in the output tuple stream. Each of these output tuples consists of the original variable bindings of the input tuple plus a binding of the new variable to one of the items in its binding collecction.
Note:
Although the binding collection is conceptually evaluated independently for each input tuple, an optimized implementation may sometimes be able to avoid re-evaluating the binding collection if it can show that the variables that the binding collection depends on have the same values as in a previous evaluation.
For a given input tuple, if the binding collection for the new variable in the for clause is empty (that is, it is anthe empty sequence or an empty arrayDM depending on whether member is specified), and if allowing empty is not specified, the input tuple generates zero output tuples (it is not represented in the output tuple stream.)
The allowing empty option is available only when processing sequences, not when processing arrays or maps. The effect is that if the binding collection is anthe empty sequence, the input tuple generates one output tuple, with the original variable bindings plus a binding of the new variable to anthe empty sequence.
Note:
If a type declaration is present and allowing empty is specified, the type declaration should include an occurrence indicator of "?" to indicate that the variable may be bound to an empty sequence.
If the new variable introduced by a for clause has an associated positional variable, the output tuples generated by the for clause also contain bindings for the positional variable. In this case, as the new variable is bound to each item in its binding collection, the positional variable is bound to the ordinal position of that item within the binding collection, starting with one. Note that, since the positional variable represents a position within a binding collection, the output tuples corresponding to each input tuple are independently numbered, starting with one. For a given input tuple, if the binding collection is empty and allowing empty is specified, the positional variable in the output tuple is bound to the integer zero.
The tuples in the output tuple stream are ordered primarily by the order of the input tuples from which they are derived, and secondarily by the order of the binding sequence for the new variable; otherwise the order of the output tuple stream is implementation-dependent.
The following examples illustrates the effects of intermediate for clauses:
Input tuple stream:
($x = 1) ($x = 2) ($x = 3) ($x = 4)
Intermediate for clause:
for $y in ($x to 3)
Output tuple stream:
($x = 1, $y = 1) ($x = 1, $y = 2) ($x = 1, $y = 3) ($x = 2, $y = 2) ($x = 2, $y = 3) ($x = 3, $y = 3)
Note:
In this example, there is no output tuple that corresponds to the input tuple ($x = 4) because, when the for clause is evaluated with the bindings in this input tuple, the resulting binding collection for $y is empty.
This example shows how the previous example would have been affected by a positional variable (assuming the same input tuple stream):
for $y at $j in ($x to 3)
Output tuple stream:
($x = 1, $y = 1, $j = 1) ($x = 1, $y = 2, $j = 2) ($x = 1, $y = 3, $j = 3) ($x = 2, $y = 2, $j = 1) ($x = 2, $y = 3, $j = 2) ($x = 3, $y = 3, $j = 1)
This example shows how the previous example would have been affected by allowing empty. Note that allowing empty causes the input tuple ($x = 4) to be represented in the output tuple stream, even though the binding sequence for $y contains no items for this input tuple. This example illustrates that allowing empty in a for clause serves a purpose similar to that of an “outer join” in a relational database query. (Assume the same input tuple stream as in the previous example.)
for $y allowing empty at $j in ($x to 3)
Output tuple stream:
($x = 1, $y = 1, $j = 1) ($x = 1, $y = 2, $j = 2) ($x = 1, $y = 3, $j = 3) ($x = 2, $y = 2, $j = 1) ($x = 2, $y = 3, $j = 2) ($x = 3, $y = 3, $j = 1) ($x = 4, $y = (), $j = 0)
This example illustrates processing of arrays:
Input tuple stream:
($x = 1) ($x = 2) ($x = 3)
Intermediate for clause:
for member $y in [[$x+1, $x+2], [[$x+3, $x+4]]
Output tuple stream:
($x = 1, $y = [ 2, 3 ]) ($x = 1, $y = [ 4, 5 ]) ($x = 2, $y = [ 3, 4 ]) ($x = 2, $y = [ 5, 6 ]) ($x = 3, $y = [ 4, 5 ]) ($x = 3, $y = [ 6, 7 ])
This example shows how a for clause that binds two variables is semantically equivalent to two for clauses that bind one variable each. We assume that this for clause occurs at the beginning of a FLWOR expression. It is equivalent to an initial single-variable for clause that provides an input tuple stream to an intermediate single-variable for clause.
for $x in (1, 2, 3, 4), $y in ($x to 3)
Output tuple stream:
($x = 1, $y = 1) ($x = 1, $y = 2) ($x = 1, $y = 3) ($x = 2, $y = 2) ($x = 2, $y = 3) ($x = 3, $y = 3)
A for clause may contain one or more type declarations, identified by the keyword as. The semantics of type declarations are defined in 4.13.1 Variable Bindings.
Changes in 4.0 (next | previous)
The value bound to a variable in a let clause is now converted to the declared type by applying the coercion rules. [Issue 189 PR 254 29 November 2022]
Sequences, arrays, and maps can be destructured in a let clause to extract their components into multiple variables. [Issue 37 PR 2055 17 June 2025]
LetClause | ::= | "let" (LetBinding ++ ",") |
LetBinding | ::= | LetValueBinding | LetSequenceBinding | LetArrayBinding | LetMapBinding |
LetValueBinding | ::= | VarNameAndType ":=" ExprSingle |
VarNameAndType | ::= | "$" EQNameTypeDeclaration? |
EQName | ::= | QName | URIQualifiedName |
TypeDeclaration | ::= | "as" SequenceType |
SequenceType | ::= | ("empty-sequence" "(" ")") |
ExprSingle | ::= | FLWORExpr |
LetSequenceBinding | ::= | "$" "(" (VarNameAndType ++ ",") ")" TypeDeclaration? ":=" ExprSingle |
LetArrayBinding | ::= | "$" "[" (VarNameAndType ++ ",") "]" TypeDeclaration? ":=" ExprSingle |
LetMapBinding | ::= | "$" "{" (VarNameAndType ++ ",") "}" TypeDeclaration? ":=" ExprSingle |
The purpose of a let clause is to bind values to one or more variables. Each variable is bound to the result of evaluating an expression.
If a let clause declares multiple variables separated by commas, it is semantically equivalent to multiple let clauses, each containing a single variable. For example, the clause
let $x := $expr1, $y := $expr2
is semantically equivalent to the following sequence of clauses:
let $x := $expr1 let $y := $expr2
After performing this expansion, the effect of a let clause is as follows:
If the let expression uses multiple variables, it is first expanded to a set of nested let expressions, each of which uses only one variable. Specifically, any separating comma is replaced by let.
In a LetValueBinding such as let $V as T := EXPR:
The variable V is declared as a range variable.
The sequence type T is called the declared type. If there is no declared type, then item()* is assumed.
The expression EXPR is evaluated, and its value is converted to the declared type by applying the coercion rules. The resulting value forms the binding sequence for the range variable.
In a LetSequenceBinding such as let $( $A1 as T1, $A2 as T2, ... , $An as Tn ) as ST := EXPR:
The sequence type ST is called the declared sequence type. If there is no declared sequence type, then item()* is assumed.
The expression EXPR is evaluated, and its value is converted to the declared sequence type ST by applying the coercion rules. Call the resulting (coerced) value V.
Each variable Ai (for i in 1 to n-1) is effectively replaced by a LetValueBinding of the form let Ai as Ti := items-at(V, i). That is, a range variable named Ai is declared, whose binding sequence is the item V[ i ], after coercion to the type Ti if specified. If Ti is absent, no further coercion takes place (the default is effectively item()?).
The last variable An is effectively replaced by a LetValueBinding of the form let An as Tn := subsequence(V, n). That is, the last variable is bound to the rest of the binding sequence (or to the empty sequence if the binding sequence has fewer items than the number of variables).
Note:
For any variable Ai, including the last, if i exceeds the length of the sequence V, then Ai is bound to anthe empty sequence. This will cause a type error if type Ti does not permit anthe empty sequence.
Note:
It is permissible to bind several variables with the same name; all but the last are occluded. A useful convention is therefore to bind items in the sequence that are of no interest to the variable $_: for example let $( $_, $_, $x ) := EXPR effectively binds $x to the subsequence starting at the third item, while causing the first two items to be ignored.
The expression:
let $( $a, $b as xs:integer, $local:c ) := (2, 4, 6) return $a + $b + $local:c
is expanded to:
let $temp := (2, 4, 6) let $a := fn:items-at($temp, 1) let $b as xs:integer := fn:items-at($temp, 2) let $local:c := fn:subsequence($temp, 3) return $a + $b + $local:c
where $temp is some variable name that is otherwise unused.
Consider the element $E := <e A="p q r" B="x y z"/>.
Then consider the expression:
let $( $a, $b ) := $E!(@A, @B)
Here the binding sequence is a sequence of two attribute nodes, so $a is bound to the attribute @A, and $b is bound to the attribute node @B.
If the operator "!" were replaced by "/", or if "," were replaced by "|", then the binding sequence would be sorted into document order, and since the order of attributes is not defined, this would make it unpredictable which variable is bound to which attribute node.
Now consider what happens when a declared sequence type is added:
let $( $a, $b ) as xs:string* := $E!(@A, @B)
The sequence of two attribute nodes is now atomized to form a sequence of strings. The first string in this sequence is bound to $a, and the remainder of the sequence is bound to $b. If the element $E is untyped, this will result in $a being bound to the xs:untypedAtomic value "p q r", while $b is bound to the xs:untypedAtomic value "x y z".
However, suppose that the element $E has been validated against a schema that defines both attributes @A and @B as list types with item type xs:string. In this case, the atomized value of $E will be a sequence of six strings. The variable $a is bound to the first of these strings (that is, "p"), while $b is bound to a sequence containing the remaining five strings (that is, ("q", "r", "x", "y", "z")).
By contrast, if the expression is written as:
let $( $a as xs:string*, $b as xs:string* ) := $E!(@A, @B)
then $a is bound to the result of atomizing the first attribute (the untypedAtomic value "p q r" in the untyped case, or the sequence of three strings ("p", "q", "r") in the schema-validated case), while $b is similarly bound to the result of atomizing the second attribute.
Consider transforming the string "Nf3 Nf6 c4 g6 Nc3 Bg7 d4 O-O Bf4 d5" (notation for the start of a chess game) to the form (["Nf3", "Nf6",] ["c4", "g6"], [ "Nc3", "Bg7"], [ "d4", "O-O"], ["Bf4", "d5"]). This can be achieved as follows:
declare function local:grouped-moves($moves) {
if (exists($moves)) {
let $($m1, $m2, $rest) := $moves
return [$m1, $m2], local:grouped-moves($rest)
}
};
local:grouped-moves(tokenize("Nf3 Nf6 c4 g6 Nc3 Bg7 d4 O-O Bf4 d5"))In a LetArrayBinding such as let $[ $A1 as T1, $A2 as T2, ... , $An as Tn ] as AT := EXPR:
The sequence type AT is called the declared array type. If there is no declared array type, then array(*) is assumed.
The expression EXPR is evaluated, and its value is converted to the declared array type AT by applying the coercion rules. A type error [err:XPTY0004] is raised if the result is not a singleton array. Call the resulting (coerced) value V.
Each variable Ai (for i in 1 to n) is effectively replaced by a LetValueBinding of the form let Ai as Ti := array:get(V, i). That is, a range variable named Ai is declared, whose binding sequence is the array member V ? i, after coercion to the type Ti if specified. If Ti is absent, no further coercion takes place (the default is effectively item()*).
Note:
If i exceeds the length of the array V, then an error [err:FOAR0001]FO is raised.
Note:
It is permissible to bind several variables with the same name; all but the last are occluded. A useful convention is therefore to bind items in the sequence that are of no interest to the variable $_: for example let $( $_, $_, $x ) := EXPR effectively binds $x to the third item in the sequence and causes the first two items to be ignored.
The expression:
let $[ $a, $b as xs:integer, $local:c ] := [ 2, 4, 6 ] return $a + $b + $local:c
is expanded to:
let $temp := [ 2, 4, 6 ] let $a := array:get($temp, 1, ()) let $b as xs:integer := array:get($temp, 2) let $local:c := array:get($temp, 3, ()) return $a + $b + $local:c
where $temp is some variable name that is otherwise unused.
In a LetMapBinding such as let ${ $A1 as T1, $A2 as T2, ... , $An as Tn } as MT := EXPR:
The sequence type MT is called the declared map type. If there is no declared map type, then map(*) is assumed.
The expression EXPR is evaluated, and its value is converted to the declared map type MT by applying the coercion rules. A type error [err:XPTY0004] is raised if the result is not a singleton map. Call the resulting (coerced) value V.
Each variable Ai (for i in 1 to n) is effectively replaced by a LetValueBinding of the form let Ai as Ti := map:get(V, "Ni", ()), where Ni is the local part of the name of the variable Ai. That is, a range variable named Ai is declared, whose binding sequence is the value of the map entry in V whose key is an xs:string (or xs:anyURI or xs:untypedAtomic) equal to the local part of the variable name, after coercion to the type Ti if specified. If Ti is absent, no further coercion takes place (the default is effectively item()*).
Note:
If there is no entry in the map with a key corresponding to the variable name, then the variable Ai is bound to anthe empty sequence. This will cause a type error if type Ti does not permit anthe empty sequence.
Note:
It is not possible to use this mechanism to bind variables to values in a map unless the keys in the map are strings in the form of NCNames.
The expression:
let ${ $a, $b as xs:integer, $local:c } := { "a": 2, "b": 4, "c": 6, "d": 8 }
return $a + $b + $local:cis expanded to:
let $temp := { "a": 2, "b": 4, "c": 6 }
let $a := map:get($temp, "a", ())
let $b as xs:integer := map:get($temp, "b", ())
let $local:c := map:get($temp, "c", ())
return $a + $b + $local:cwhere $temp is some variable name that is otherwise unused.
The effect of the LetClause is to add one or more variable bindings to the tuple stream. Specifically, each range variable declared within the LetClause is bound to its corresponding binding sequence, and the resulting variable binding is added to the current tuple, replacing any existing variable binding with the same variable name.
If the LetClause is the initial clause in a FLWOR expression, it creates an initial tuple for the tuple stream, containing these variable bindings. This tuple stream serves as input to the next clause in the FLWOR expression.
If the LetClause is an intermediate clause in a FLWOR expression, it adds the relevant variable bindings to each tuple in the input tuple stream. The resulting tuples become the output tuple stream of the let clause.
The number of tuples in the output tuple stream of an intermediate let clause is the same as the number of tuples in the input tuple stream. The number of variable bindings in the output tuples is always greater than the number of variable bindings in the input tuples, unless the input tuples already contain bindings for every variable binding created by the LetClause; in this case, the new binding for any given variable name occludes (replaces) an earlier binding for that variable name, and the number of bindings is unchanged.
The semantics of type declarations are further defined in 4.13.1 Variable Bindings.
The following code fragment illustrates how a for clause and a let clause can be used together. The for clause produces an initial tuple stream containing a binding for variable $d to each department number found in a given input document. The let clause adds an additional binding to each tuple, binding variable $e to a sequence of employees whose department number matches the value of $d in that tuple.
for $d in doc("depts.xml")/depts/deptno
let $e := doc("emps.xml")/emps/emp[deptno eq $d]GroupByClause | ::= | "group" "by" (GroupingSpec ++ ",") |
GroupingSpec | ::= | VarName (TypeDeclaration? ":=" ExprSingle)? ("collation" URILiteral)? |
VarName | ::= | "$" EQName |
EQName | ::= | QName | URIQualifiedName |
TypeDeclaration | ::= | "as" SequenceType |
SequenceType | ::= | ("empty-sequence" "(" ")") |
ExprSingle | ::= | FLWORExpr |
URILiteral | ::= | StringLiteral |
StringLiteral | ::= | AposStringLiteral | QuotStringLiteral |
| /* ws: explicit */ |
A group by clause generates an output tuple stream in which each tuple represents a group of tuples from the input tuple stream that have equivalent grouping keys. We will refer to the tuples in the input tuple stream as pre-grouping tuples, and the tuples in the output tuple stream as post-grouping tuples.
The group by clause assigns each pre-grouping tuple to a group, and generates one post-grouping tuple for each group. In the post-grouping tuple for a group, each grouping key is represented by a variable that was specified in a GroupingSpec, and every variable that appears in the pre-grouping tuples that were assigned to that group is represented by a variable of the same name, bound to a sequence of all values bound to the variable in any of these pre-grouping tuples. Subsequent clauses in the FLWOR expression see only the variable bindings in the post-grouping tuples; they no longer have access to the variable bindings in the pre-grouping tuples. The number of post-grouping tuples is less than or equal to the number of pre-grouping tuples.
A group by clause contains one or more grouping specifications, as shown in the grammar. [Definition: Each grouping specification specifies one grouping variable, which refers to variable bindings in the pre-grouping tuples. The values of the grouping variables are used to assign pre-grouping tuples to groups.] Each grouping specification may optionally provide an expression to which its grouping variable is bound. If no expression is provided, the grouping variable name must be equal (by the eq operator on expanded QNames) to the name of a variable in the input tuple stream, and it refers to that variable; otherwise a static error is raised [err:XQST0094]. For each grouping specification that contains a binding expression, a let binding is created in the pre-grouping tuples, and the grouping variable refers to that let binding. For example, the clause:
group by $g1, $g2 := $expr1, $g3 := $expr2 collation "Spanish"
is semantically equivalent to the following sequence of clauses:
let $g2 := $expr1 let $g3 := $expr2 group by $g1, $g2, $g3 collation "Spanish"
The process of group formation proceeds as follows:
[Definition: The atomized value of a grouping variable is called a grouping key.] For each pre-grouping tuple, the grouping keys are created by atomizing the values of the grouping variables (in the post-grouping tuples, each grouping variable is set to the value of the corresponding grouping key, as discussed below). If the value of any grouping variable consists of more than one item, a type error is raised [err:XPTY0004]. If a type declaration is present and the resulting atomized value is not an instance of the specified type, a type error is raised [err:XPTY0004].
The input tuple stream is partitioned into groups of tuples whose grouping keys are equivalent. [Definition: Two tuples T1 and T2 have equivalent grouping keys if and only if, for each grouping variable GV, the atomized value of GV in T1 is deep-equal to the atomized value of GV in T2, as defined by applying the function fn:deep-equal using the appropriate collation.]
Note:
The fn:deep-equal function has been changed in XQuery 4.0 so that it is now transitive; the problem that existed in earlier versions when comparing numeric values of different types has thereby been resolved.
Note:
The atomized grouping key will always be either anthe empty sequence or a single atomic item. Defining equivalence by reference to the fn:deep-equal function ensures that the empty sequence is equivalent only to the empty sequence, that NaN is equivalent to NaN, that xs:untypedAtomic items are compared as strings, and that values from different atomic type familiesDM are considered non-equivalent.
The appropriate collation for comparing two grouping keys is the collation specified in the pertinent GroupingSpec if present, or the default collation from the dynamic context otherwise. If the collation is specified by a relative URI, that relative URI is resolved to an absolute URI using the Static Base URI. If the specified collation is not found in statically known collations, a static error is raised [err:XQST0076].
Each group of tuples produced by the above process results in one post-grouping tuple. The pre-grouping tuples from which the group is derived have equivalentgrouping keys, but these keys are not necessarily identical (for example, the strings "Frog" and "frog" might be equivalent according to the collation in use.) In the post-grouping tuple, each grouping variable is bound to the value of the corresponding grouping key.
In the post-grouping tuple generated for a given group, each non-grouping variable is bound to a sequence containing the concatenated values of that variable in all the pre-grouping tuples that were assigned to that group. The values derived from individual tuples are concatenated in a way that preserves the order of the pre-grouping tuple stream.
Note:
This behavior may be surprising to SQL programmers, since SQL reduces the equivalent of a non-grouping variable to one representative value. Consider the following query:
let $x := 64000
for $c in //customer
where $c/salary > $x
group by $d := $c/department
return <department name="{ $d }">
Number of employees earning more than ${ $x } is { count($c) }
</department>If there are three qualifying customers in the sales department this evaluates to:
<department name="sales"> Number of employees earning more than $64000 64000 64000 is 3 </department>
In XQuery, each group is a sequence of items that match the group by criteria—in a tree-structured language like XQuery, this is convenient, because further structures can be built based on the items in this sequence. Because there are three items in the group, $x evaluates to a sequence of three items. To reduce this to one item, use fn:distinct-values():
let $x := 64000
for $c in //customer
let $d := $c/department
where $c/salary > $x
group by $d
return <department name="{ $d }">
Number of employees earning more than ${ distinct-values($x) } is { count($c) }
</department>Note:
In general, the static type of a variable in a post-grouping tuple is different from the static type of the variable with the same name in the pre-grouping tuples.
The order in which tuples appear in the post-grouping tuple stream is implementation-dependent.
Note:
An order by clause can be used to impose a value-based ordering on the post-grouping tuple stream. Similarly, if it is desired to impose a value-based ordering within a group (i.e., on the sequence of items bound to a non-grouping variable), this can be accomplished by a nested FLWOR expression that iterates over these items and applies an order by clause. In some cases, a value-based ordering within groups can be accomplished by applying an order by clause on a non-grouping variable before applying the group by clause.
A group by clause rebinds all the variables in the input tuple stream. The scopes of these variables are not affected by the group by clause, but in post-grouping tuples the values of the variables represent group properties rather than properties of individual pre-grouping tuples.
Examples:
This example illustrates the effect of a group by clause on a tuple stream.
Input tuple stream:
($storeno = <storeno>S101</storeno>, $itemno = <itemno>P78395</itemno>) ($storeno = <storeno>S102</storeno>, $itemno = <itemno>P94738</itemno>) ($storeno = <storeno>S101</storeno>, $itemno = <itemno>P41653</itemno>) ($storeno = <storeno>S102</storeno>, $itemno = <itemno>P70421</itemno>)
group by clause:
group by $storeno
Output tuple stream:
($storeno = S101, $itemno = (<itemno>P78395</itemno>, <itemno>P41653</itemno>)) ($storeno = S102, $itemno = (<itemno>P94738</itemno>, <itemno>P70421</itemno>))
This example and the ones that follow are based on two separate sequences of elements, named $sales and $products. We assume that the variable $sales is bound to a sequence of elements with the following structure:
<sales> <storeno>S101</storeno> <itemno>P78395</itemno> <qty>125</qty> </sales>
We also assume that the variable $products is bound to a sequence of elements with the following structure:
<product> <itemno>P78395</itemno> <price>25.00</price> <category>Men's Wear</category> </product>
The simplest kind of grouping query has a single grouping variable. The query in this example finds the total quantity of items sold by each store:
for $s in $sales
let $storeno := $s/storeno
group by $storeno
return <store number="{ $storeno }" total-qty="{ sum($s/qty) }"/>The result of this query is a sequence of elements with the following structure:
<store number="S101" total-qty="1550" /> <store number="S102" total-qty="2125" />
In a more realistic example, a user might be interested in the total revenue generated by each store for each product category. Revenue depends on both the quantity sold of various items and the price of each item. The following query joins the two input sequences and groups the resulting tuples by two grouping variables:
for $s in $sales
for $p in $products[itemno = $s/itemno]
let $revenue := $s/qty * $p/price
group by $storeno := $s/storeno,
$category := $p/category
return <summary storeno="{ $storeno }"
category="{ $category }"
revenue="{ sum($revenue) }"/>The result of this query is a sequence of elements with the following structure:
<summary storeno="S101" category="Men's Wear" revenue="10185"/> <summary storeno="S101" category="Stationery" revenue="4520"/> <summary storeno="S102" category="Men's Wear" revenue="9750"/> <summary storeno="S102" category="Appliances" revenue="22650"/> <summary storeno="S102" category="Jewelry" revenue="30750"/>
The result of the previous example was a “flat” list of elements. A user might prefer the query result to be presented in the form of a hierarchical report, grouped primarily by store (in order by store number) and secondarily by product category. Within each store, the user might want to see only those product categories whose total revenue exceeds $10,000, presented in descending order by their total revenue. This report is generated by the following query:
for $s1 in $sales
let $storeno := $s1/storeno
group by $storeno
order by $storeno
return <store storeno="{ $storeno }">{
for $s2 in $s1
for $p in $products[itemno = $s2/itemno]
let $category := $p/category
let $revenue := $s2/qty * $p/price
group by $category
let $group-revenue := sum($revenue)
where $group-revenue > 10000
order by $group-revenue descending
return <category name="{ $category }" revenue="{ $group-revenue }"/>
}</store>The result of this example query has the following structure:
<store storeno="S101"> <category name="Men's Wear" revenue="10185"/> </store> <store storeno="S102"> <category name="Jewelry" revenue="30750"/> <category name="Appliances" revenue="22650"/> </store>
The following example illustrates how to avoid a possible pitfall in writing grouping queries.
In each post-grouping tuple, all variables except for the grouping variable are bound to sequences of items derived from all the pre-grouping tuples from which the group was formed. For instance, in the following query, $high-price is bound to a sequence of items in the post-grouping tuple.
let $high-price := 1000
for $p in $products[price > $high-price]
let $category := $p/category
group by $category
return <category name="{ $category }">{
count($p) || ' products have price greater than ' || $high-price || '.'
}</category>If three products in the “Men’s Wear” category have prices greater than 1000, the result of this query might look (in part) like this:
<category name="Men’s Wear"> 3 products have price greater than 1000 1000 1000. </category>
The repetition of "1000" in this query result is due to the fact that $high-price is not a grouping variable. One way to avoid this repetition is to move the binding of $high-price to an outer-level FLWOR expression, as follows:
let $high-price := 1000
return (
for $p in $products[price > $high-price]
let $category := $p/category
group by $category
return <category name="{ $category }">{
count($p) || ' products have price greater than ' || $high-price || '.'
}</category>
)The result of the revised query might contain the following element:
<category name="Men's Wear"> 3 products have price greater than 1000. </category>
Note:
If a collation name is specified, it must be supplied as a literal string; it cannot be computed dynamically. A workaround in such cases is to use the fn:collation-key function. For example:
for $p in $products group by collation-key($p/description, $collation) return $product/@code
Note however that the fn:collation-key function might not work for all collations.
Note:
Grouping can also be achieved by constructing a map. For example, the function call map:build(//employee, fn { department }) constructs a map in which employees are grouped by department.
Most modern programming languages have support for collections of key/value pairs, which may be called maps, dictionaries, associative arrays, hash tables, keyed lists, or objects (these are not the same thing as objects in object-oriented systems). In XQuery 4.0, we call these maps. Most modern programming languages also support ordered lists of values, which may be called arrays, vectors, or sequences. In XQuery 4.0, we have both sequences and arrays. Unlike sequences, an array is an item, and can appear as an item in a sequence.
Note:
The XQuery 4.0 specification focuses on syntax provided for maps and arrays, especially constructors and lookup.
Some of the functionality typically needed for maps and arrays is provided by functions defined in [Functions and Operators 4.0] section 14 Processing maps and [Functions and Operators 4.0] section 15 Processing arrays, including functions used to read JSON to create maps and arrays, serialize maps and arrays to JSON, combine maps to create a new map, remove map entries to create a new map, iterate over the keys of a map, convert an array to create a sequence, combine arrays to form a new array, and iterate over arrays in various ways.
The operator "?", known as the lookup operator, returns values found in the operand map or array.
Lookup expressions are retained in this specification with only minor changes from the previous version 3.1. They remain a convenient solution for simple lookups of entries in maps and arrays.
For more complex queries into trees of maps and arrays, XQuery 4.0 introduces a generalization of path expressions (see 4.6 Path Expressions) which can now handle JTrees as well as XTrees.
For simple expressions, the capabilities of the two constructs overlap. For example, if $m is a map, then the expressions $m?code = 3 and $m/code = 3 have the same effect. Path expressions, however, have more power, and with it, more complexity. The expression $m/code = 3 (unless simplified by an optimizer) effectively expands the expression to (jtree($m)/child::get("code") => jnode-content()) = 3: that is, the supplied map is wrapped in a JNode, the child axis returns a sequence of JNodes, and the ·content· properties of these JNodes are compared with the supplied value 3.
Whereas simple lookups of specific entries in maps and arrays work well, experience has shown that the ?* wildcard lookup can be problematic. This is because of the flattening effect: for example, given the array let $A := [(1,2), (3,4), (), 5] the result of the expression $A?* is the sequence (1, 2, 3, 4, 5) which loses information that might be needed for further processing. By contrast, the path expression $A/* (or $A/child::*) returns a sequence of four JNodes, whose ·content· properties are respectively (1,2), (3,4), (), and 5.
The result of a lookup expression is a simple value (the value of an entry in a map or a member of an array, or the sequence concatenation of several such values). By contrast, the result of a path expression applied to maps or arrays is always a sequence of JNodes. These JNodes can be used for further navigation. If only the ·content· properties of the JNodes are needed, these will usually be extracted automatically by virtue of the coercion rules: for example if the value is used in an arithmetic expression or a value comparison, atomization of the JNode automatically extracts its ·content·. In other cases the value can be extracted explicitly by a call of the jnode-content function.
Lookup expressions on arrays result in a dynamic error if the subscript is out of bounds, whereas the equivalent path expression succeeds, returning anthe empty sequence. For example array{1 to 5}?10 raises [err:FOAY0001]FO40, whereas array{1 to 5}/get(10) returns a empty sequence.
Changes in 4.0 (next | previous)
Filter expressions for maps and arrays are introduced. [Issue 1159 PR 1163 20 April 2024]
Predicates in filter expressions for maps and arrays can now be numeric. [Issue 1207 PR 1217 15 May 2024]
The group is considering removing or substantially changing this feature, it is considered at risk. [Issue 2351 ]
FilterExprAM | ::= | PostfixExpr "?[" Expr "]" |
PostfixExpr | ::= | PrimaryExpr | FilterExpr | DynamicFunctionCall | LookupExpr | MethodCall | FilterExprAM |
Expr | ::= | (ExprSingle ++ ",") |
Maps and arrays can be filtered using the construct INPUT?[FILTER]. For example, $array?[count(.)=1] filters an array to retain only those members that are single items.
Note:
The character-pair ?[ forms a single token; no intervening whitespace or comment is allowed.
The required type of the left-hand operand INPUT is (map(*)|array(*))?: that is, it must be either anthe empty sequence, a single map, or a single array [err:XPTY0004]. However, the coercion rules also allow a JNode whose ·content· is a map or array to be supplied. If the value is anthe empty sequence, the result of the expression is anthe empty sequence.
If the value of INPUT is an array, then the FILTER expression is evaluated for each member of the array, with that member as the context value, with its position in the array as the context position, and with the size of the array as the context size. The result of the expression is an array containing those members of the input array for which the predicate truth value of the FILTER expression is true. The order of retained members is preserved.
For example, the following expression:
let $array := [ (), 1, (2, 3), (4, 5, 6) ] return $array?[count(.) ge 2]
returns:
[ (2, 3), (4, 5, 6) ]
Note:
Numeric predicates are handled in the same way as with filter expressions for sequences. However, the result is always an array, even if only one member is selected. For example, given the $array shown above, the result of $array?[3] is the single-member arrayDM[ (2, 3) ]. Contrast this with $array?3 which delivers the sequence 2, 3.
If the value of INPUT is a map, then the FILTER expression is evaluated for each entry in the map, with the context value set to an item of type record(key as xs:anyAtomicType, value as item()*), in which the key and value fields represent the key and value of the map entry. The context position is the position of the entry in the map (in entry orderDM), and the context size is the number of entries in the map. The result of the expression is a map containing those entries of the input map for which the predicate truth value of the FILTER expression is true. The relative order of entries in the result retains the relative order of entries in the input.
For example, the following expression:
let $map := { 1: "alpha", 2: "beta", 3: "gamma" }
return $map?[?key ge 2]returns:
{ 2: "beta", 3: "gamma" }Note:
A filter expression such as $map?[last()-1, last()] might be used to return the last two entries of a map in entry orderDM.
OtherwiseExpr | ::= | StringConcatExpr ("otherwise" StringConcatExpr)* |
StringConcatExpr | ::= | RangeExpr ("||" RangeExpr)* |
The otherwise expression returns the value of its first operand, unless this is anthe empty sequence, in which case it returns the value of its second operand.
For example, @price - (@discount otherwise 0) returns the value of @price - @discount, if the attribute @discount exists, or the value of @price if the @discount attribute is absent.
To prevent spurious errors, the right hand operand is guarded: it cannot throw any dynamic error unless the left-hand operand returns anthe empty sequence.
Note:
The operator is associative (even under error conditions): A otherwise (B otherwise C) returns the same result as (A otherwise B) otherwise C.
The otherwise operator binds more tightly than comparison operators such as =, but less tightly than string concatenation (||) or arithemetic operators. The expression $a = @x otherwise @y + 1 parses as $a = (@x otherwise (@y + 1)).
Changes in 4.0 (next | previous)
Switch expressions now allow a case clause to match multiple atomic items. [Issue 328 PR 364 7 March 2023]
Switch and typeswitch expressions can now be written with curly brackets, to improve readability. [Issue 365 PR 587 7 November 2023]
The comparand expression in a switch expression can be omitted, allowing the switch cases to be provided as arbitrary boolean expressions. [Issue 671 PR 678 12 September 2023]
SwitchExpr | ::= | "switch" SwitchComparand (SwitchCases | BracedSwitchCases) |
SwitchComparand | ::= | "(" Expr? ")" |
Expr | ::= | (ExprSingle ++ ",") |
SwitchCases | ::= | SwitchCaseClause+ "default" "return" ExprSingle |
SwitchCaseClause | ::= | ("case" SwitchCaseOperand)+ "return" ExprSingle |
SwitchCaseOperand | ::= | Expr |
ExprSingle | ::= | FLWORExpr |
BracedSwitchCases | ::= | "{" SwitchCases "}" |
The switch expression chooses one of several expressions to evaluate based on the input value.
In a switch expression, the switch keyword is followed by an expression enclosed in parentheses, called the switch comparand. This is the expression whose value is being compared. This expression is optional, and defaults to true. The remainder of the switch expression consists of one or more case clauses, with one or more case operand expressions each, and a default clause.
The first step in evaluating a switch expression is to apply atomization to the value of the switch comparand. Call the result the switch value. If the switch value is a sequence of length greater than one, a type error is raised [err:XPTY0004]. In the absence of a switch comparand, the switch value is the xs:boolean value true.
The switch value is compared to each SwitchCaseOperand in turn until a match is found or the list is exhausted. The matching is performed as follows:
The SwitchCaseOperand is evaluated.
The resulting value is atomized: call this the case value.
If the case value is anthe empty sequence, then a match occurs if and only if the switch value is anthe empty sequence.
Otherwise, the singletonswitch value is compared individually with each item in the case value in turn, and a match occurs if and only if these two atomic items are contextually equalFO, using the default collation in the static context.
[Definition: The effective case of a switch expression is the first case clause that matches, using the rules given above, or the default clause if no such case clause exists.] The value of the switch expression is the value of the return expression in the effective case.
Switch expressions have rules regarding the propagation of dynamic errors: see 2.5.5 Guarded Expressions. These rules mean that the return clauses of a switch expression must not raise any dynamic errors except in the effective case. Dynamic errors raised in the operand expressions of the switch or the case clauses are propagated; however, an implementation must not raise dynamic errors in the operand expressions of case clauses that occur after the effective case. An implementation is permitted to raise dynamic errors in the operand expressions of case clauses that occur before the effective case, but not required to do so.
The following example shows how a switch expression might be used:
switch ($animal) {
case "Cow" return "Moo"
case "Cat" return "Meow"
case "Duck", "Goose" return "Quack"
default return "What's that odd noise?"
}The curly brackets in a switch expression are optional. The above example can equally be written:
switch ($animal) case "Cow" return "Moo" case "Cat" return "Meow" case "Duck", "Goose" return "Quack" default return "What's that odd noise?"
The following example illustrates a switch expression where the comparand is defaulted to true:
switch () {
case ($a le $b) return "lesser"
case ($a ge $b) return "greater"
case ($a eq $b) return "equal"
default return "not comparable"
}Note:
The comparisons are performed using the fn:deep-equal function, after atomization. This means that a case expression such as @married tests fn:data(@married) rather than fn:boolean(@married). If the effective boolean value of the expression is wanted, this can be achieved with an explicit call of fn:boolean.
Quantified expressions support existential and universal quantification. The value of a quantified expression is always true or false.
QuantifiedExpr | ::= | ("some" | "every") (QuantifierBinding ++ ",") "satisfies" ExprSingle |
QuantifierBinding | ::= | VarNameAndType "in" ExprSingle |
VarNameAndType | ::= | "$" EQNameTypeDeclaration? |
EQName | ::= | QName | URIQualifiedName |
TypeDeclaration | ::= | "as" SequenceType |
SequenceType | ::= | ("empty-sequence" "(" ")") |
ExprSingle | ::= | FLWORExpr |
A quantified expression begins with a quantifier, which is the keyword some or every, followed by one or more in-clauses that are used to bind variables, followed by the keyword satisfies and a test expression. Each in-clause associates a variable with an expression that returns a sequence of items, called the binding sequence for that variable. The value of the quantified expression is defined by the following rules:
If the QuantifiedExpr contains more than one QuantifierBinding, then it is equivalent to the expression obtained by replacing each comma with satisfies some or satisfies every respectively. For example, the expression some $x in X, $y in Y satisfies $x = $y is equivalent to some $x in X satisfies some $y in Y satisfies $x = $y, while the expression every $x in X, $y in Y satisfies $x lt $y is equivalent to every $x in X satisfies every $y in Y satisfies $x lt $y
If the quantifier is some, the QuantifiedExpr returns true if at least one evaluation of the test expression has the effective boolean valuetrue; otherwise it returns false. In consequence, if the binding sequence is empty, the result of the QuantifiedExpr is false.
If the quantifier is every, the QuantifiedExpr returns true if every evaluation of the test expression has the effective boolean valuetrue; otherwise it returns false. In consequence, if the binding sequence is empty, the result of the QuantifiedExpr is true.
The scope of a variable bound in a quantified expression comprises all subexpressions of the quantified expression that appear after the variable binding. The scope does not include the expression to which the variable is bound.
Each variable binding may be accompanied by a type declaration, which consists of the keyword as followed by the static type of the variable, declared using the syntax in 3.1 Sequence Types. The type declaration defines a required type for the value. At run-time, the supplied value for the variable is converted to the required type by applying the coercion rules. If conversion is not possible, a type error is raised [err:XPTY0004].
The order in which test expressions are evaluated for the various items in the binding sequence is implementation-dependent. If the quantifier is some, an implementation may return true as soon as it finds one item for which the test expression has an effective boolean value of true, and it may raise a dynamic error as soon as it finds one item for which the test expression raises an error. Similarly, if the quantifier is every, an implementation may return false as soon as it finds one item for which the test expression has an effective boolean value of false, and it may raise a dynamic error as soon as it finds one item for which the test expression raises an error. As a result of these rules, the value of a quantified expression is not deterministic in the presence of errors, as illustrated in the examples below.
Here are some examples of quantified expressions:
This expression is true if every part element has a discounted attribute (regardless of the values of these attributes):
every $part in /parts/part satisfies $part/@discounted
This expression is true if at least one employee element satisfies the given comparison expression:
some $emp in /emps/employee satisfies $emp/bonus > 0.25 * $emp/salary
This expression is true if every employee element has at least one salary child with the attribute current="true":
every $emp in /emps/employee satisfies ( some $sal in $emp/salary satisfies $sal/@current = 'true' )
Note:
Like many quantified expressions, this can be simplified. This example can be written every $emp in /emps/employee satisfies $emp/salary[@current = 'true'], or even more concisely as empty(/emps/employee[not(salary/@current = 'true')].
Another alternative in XQuery 4.0 is to use the higher-order functions fn:some and fn:every. This example can be written every(/emps/employee, fn { salary/@current = 'true' })
In the following examples, each quantified expression evaluates its test expression over nine pairs of items, formed from the Cartesian product of the sequences (1, 2, 3) and (2, 3, 4). The expression beginning with some evaluates to true, and the expression beginning with every evaluates to false.
some $x in (1, 2, 3), $y in (2, 3, 4) satisfies $x + $y = 4
every $x in (1, 2, 3), $y in (2, 3, 4) satisfies $x + $y = 4
This quantified expression may either return true or raise a type error, since its test expression returns true for one item and raises a type error for another:
some $x in (1, 2, "cat") satisfies $x * 2 = 4
This quantified expression may either return false or raise a type error, since its test expression returns false for one item and raises a type error for another:
every $x in (1, 2, "cat") satisfies $x * 2 = 4
This quantified expression returns true, because the binding sequence is empty, despite the fact that the condition can never be satisfied:
every $x in () satisfies ($x lt 0 and $x gt 0)
This quantified expression is implausible because it will always fail with a type error except in the case where $input is anthe empty sequence. If $input contains one or more xs:date values, a processor must raise a type error on the grounds that an xs:date cannot be compared to an xs:integer. If $input is empty, the processor may (or may not) report this error:
every $x as xs:date in $input satisfies ($x lt 0)
This quantified expression contains a type declaration that is not satisfied by every item in the test expression. The expression may either return true or raise a type error.
some $x as xs:integer in (1, 2, "cat") satisfies $x * 2 = 4
Changes in 4.0 (next | previous)
A new variable $err:map is available, capturing all error information in one place. [Issue 32 PR 493 16 May 2023]
$err:stack-trace provides information about the current state of execution. [Issue 689 PR 1470 1 October 2024]
A finally clause can be supplied, which will always be evaluated after the expressions of the try/catch clauses. [Issue 501 PR 1914 4 April 2025]
The try/catch expression provides error handling for dynamic errors and type errors raised during dynamic evaluation, including errors raised by the XQuery implementation and errors explicitly raised in a query using the fn:error() function.
TryCatchExpr | ::= | TryClause ((CatchClause+ FinallyClause?) | FinallyClause) |
TryClause | ::= | "try" EnclosedExpr |
EnclosedExpr | ::= | "{" Expr? "}" |
CatchClause | ::= | "catch" NameTestUnionEnclosedExpr |
NameTestUnion | ::= | (NameTest ++ "|") |
NameTest | ::= | EQName | Wildcard |
EQName | ::= | QName | URIQualifiedName |
Wildcard | ::= | "*" |
| /* ws: explicit */ | ||
FinallyClause | ::= | "finally" EnclosedExpr |
A try/catch expression catches dynamic errors and type errors raised by the evaluation of the target expression of the try clause. If the content expression of the try clause does not raise a dynamic error or a type error, the result of the try/catch expression is the result of the content expression.
If the target expression raises a dynamic error or a type error, the result of the try/catch expression is obtained by evaluating the first catch clause that “matches” the error value, as described below. If no catch clause “matches” the error value, then the try/catch expression raises the error that was raised by the target expression. A catch clause with one or more NameTests matches any error whose error code matches one of these NameTests. For instance, if the error code is err:FOER0000, then it matches a catch clause whose ErrorList is err:FOER0000 | err:FOER0001. Wildcards may be used in NameTests; thus, the error code err:FOER0000 also matches a catch clause whose ErrorList is err:* or *:FOER0000 or *.
Within the scope of the catch clause, a number of variables are implicitly declared, giving information about the error that occurred. These variables are initialized as described in the following table:
| Variable | Type | Value |
|---|---|---|
$err:code | xs:QName | The error code |
$err:description | xs:string? | A description of the error condition; anthe empty sequence if no description is available (for example, if the error function was called with one argument). |
$err:value | item()* | Value associated with the error. For an error raised by calling the error function, this is the value of the third argument (if supplied). |
$err:module | xs:string? | The URI (or system ID) of the module containing the expression where the error occurred, or anthe empty sequence if the information is not available. |
$err:line-number | xs:integer? | The line number within the module where the error occurred, or anthe empty sequence if the information is not available. The value may be approximate. |
$err:column-number | xs:integer? | The column number within the module where the error occurred, or anthe empty sequence if the information is not available. The value may be approximate. |
$err:stack-trace | xs:string? | Implementation-dependent information about the current state of execution, or anthe empty sequence if no stack trace is available. The variable must be bound so that a query can reference it without raising an error. |
$err:additional | item()* | Implementation-defined. Allows implementations to provide any additional information that might be useful. The variable must be bound so that a query can reference it without raising an error. |
$err:map | map(*) | A map with entries for all values that are bound to the variables above. The local names of the variables are assigned as keys. No map entries are created for those values that are empty sequences. The variable can be used to pass on all error information to another function. |
Try/catch expressions have a special rule for propagating dynamic errors. The try/catch expression ignores any dynamic errors encountered in catch clauses other than the first catch clause that matches an error raised by the try clause, and these catch clause expressions need not be evaluated.
Static errors are not caught by the try/catch expression.
If a function call occurs within a try clause, errors raised by evaluating the corresponding function are caught by the try/catch expression. If a variable reference is used in a try clause, errors raised by binding a value to the variable are not caught unless the binding expression occurs within the try clause.
Note:
The presence of a try/catch expression does not prevent an implementation from using a lazy evaluation strategy, nor does it prevent an optimizer performing expression rewrites. However, if the evaluation of an expression inside a try/catch is rewritten or deferred in this way, it must take its try/catch context with it. Similarly, expressions that were written outside the try/catch expression may be evaluated inside the try/catch, but only if they retain their original try/catch behavior. The presence of a try/catch does not change the rules that allow the processor to evaluate expressions in such a way that may avoid the detection of some errors.
If a concluding finally clause exists, its expression will be evaluated after the expressions of the try clause and a possibly evaluated catch clause. If it raises an error, this error is returned instead of a result or an error that resulted from a try or catch expression. If it raises no error, it must yield anthe empty sequence; otherwise, a type error is raised [err:XQTY0153].
Note:
A finally clause can be used to ensure that an expression will always be evaluated, no matter if the try expression is successful or if it fails. For example, fn:message can be called in the finally clause to ensure that an expression has been evaluated even if an error is raised.
Note:
If try and finally clauses are specified, catch clauses can be omitted.
Here are some examples of try/catch expressions.
A try/catch expression without name tests catches any error:
try {
$x cast as xs:integer
} catch * {
0
}With the following catch clause, only err:FORG0001 is caught:
try {
$x cast as xs:integer
} catch err:FORG0001 {
0
}This try/catch expression specifies that errors err:FORG0001 and err:XPTY0004 are caught:
try {
$x cast as xs:integer
} catch err:FORG0001 | err:XPTY0004 {
0
}Note:
In some implementations, err:XPTY0004 is detected during static evaluation; it can only be caught if it is raised during dynamic evaluation.
This try/catch expression shows how to return information about the error using implicitly defined error variables:
try {
error(#err:FOER0000)
} catch * {
$err:code, $err:value, " module: ",
$err:module, "(", $err:line-number, ",", $err:column-number, ")"
}Errors raised by using the result of a try/catch expression are not caught, since they are outside the scope of the try expression.
declare function local:thrice($x as xs:integer) as xs:integer {
3 * $x
};
local:thrice(try { "oops" } catch * { 3 } )In this example, the try block succeeds, returning the string "oops", which is not a valid argument to the function.
All available information about the error is serialized:
try {
1 + <empty/>
} catch * {
serialize($err:map, { 'method': 'adaptive' })
}fn:message will always be called, no matter if the division succeeds:
for $i in 0 to 2
return try {
1 div $i
} catch err:FOAR0001 {
'division error'
} finally {
message('1 was divided by ' || $i)
} The instance of, cast, castable, and treat expressions are used to test whether a value conforms to a given type or to convert it to an instance of a given type.
CastExpr | ::= | PipelineExpr ("cast" "as" CastTarget "?"?)? |
PipelineExpr | ::= | ArrowExpr ("->" ArrowExpr)* |
CastTarget | ::= | TypeName | ChoiceItemType | EnumerationType |
TypeName | ::= | EQName |
EQName | ::= | QName | URIQualifiedName |
ChoiceItemType | ::= | "(" (ItemType ++ "|") ")" |
ItemType | ::= | RegularItemType | FunctionType | TypeName | ChoiceItemType |
EnumerationType | ::= | "enum" "(" (StringLiteral ++ ",") ")" |
Sometimes it is necessary to convert a value to a specific datatype. For this purpose, XQuery 4.0 provides a cast expression that creates a new value of a specific type based on an existing value. A cast expression takes two operands: an input expression and a target type. The type of the atomized value of the input expression is called the input type. The target type must be a generalized atomic type. In practice this means it may be any of:
The name of an named item type defined in the static context, which in turn must refer to an item type in one of the following categories.
The name of a type defined in the in-scope schema types, which must be a simple type (of variety atomic, list or union) [err:XQST0052] . In addition, the target type cannot be xs:NOTATION, xs:anySimpleType, or xs:anyAtomicType
A ChoiceItemType representing a generalized atomic type (such as (xs:date | xs:dateTime)).
An EnumerationType such as enum("red", "green", "blue").
Otherwise, a static error is raised [err:XPST0080].
The optional occurrence indicator ? denotes that anthe empty sequence is permitted.
Casting a node to xs:QName can cause surprises because it uses the static context of the cast expression to provide the namespace bindings for this operation. Instead of casting to xs:QName, it is generally preferable to use the fn:QName function, which allows the namespace context to be taken from the document containing the QName.
The semantics of the cast expression are as follows:
The input expression is evaluated.
The result of the first step is atomized.
If the result of atomization is a sequence of more than one atomic item, a type error is raised [err:XPTY0004].
If the result of atomization is anthe empty sequence:
If ? is specified after the target type, the result of the cast expression is anthe empty sequence.
If ? is not specified after the target type, a type error is raised [err:XPTY0004].
If the result of atomization is a single atomic item, the result of the cast expression is determined by casting to the target type as described in [Functions and Operators 4.0] section 23 Casting. When casting, an implementation may need to determine whether one type is derived by restriction from another. An implementation can determine this either by examining the in-scope schema definitions or by using an alternative, implementation-dependent mechanism such as a data dictionary. The result of a cast expression is one of the following:
A value of the target type (or, in the case of list types, a sequence of values that are instances of the item type of the list type).
A type error, if casting from the source type to the target type is not supported (for example attempting to convert an integer to a date).
A dynamic error, if the particular input value cannot be converted to the target type (for example, attempting to convert the string "three" to an integer).
Note:
Casting to an enumeration type relies on the fact that an enumeration type is a generalized atomic type. So the expression cast $x as enum("red", "green") has the following effect:
If $x is an instance of xs:string, the expression returns $x unchanged if it is one of the permitted strings, and raises a dynamic error otherwise;
In other cases, the expression first casts $x to xs:string, and then proceeds as above.
An absolute path expression is an instance of the production AbsolutePathExpr: it consists of either (a) the operator / followed by zero or more operands separated by / or // operators, or (b) the operator // followed by one or more operands separated by / or // operators.
An and expression is a non-trivial instance of the production AndExpr.
An anonymous function is a function item with no name. Anonymous functions may be created, for example, by evaluating an inline function expression or by partial function application.
Application functions are function definitions written in a host language such as XQuery or XSLT whose syntax and semantics are defined in this family of specifications. Their behavior (including the rules determining the static and dynamic context) follows the rules for such functions in the relevant host language specification.
An argument to a function call is either an argument expression or an ArgumentPlaceholder (?); in both cases it may either be supplied positionally, or identified by a name (called a keyword).
A function definition has an arity range, which is a range of consecutive non-negative integers. If the function definition has M required parameters and N optional parameters, then its arity range is from M to M+N inclusive.
An array is a function item that associates a set of positions, represented as positive integer keys, with values.
The value associated with a given key is called the associated value of the key.
An atomic item is a value in the value space of an atomic type, as defined in [XML Schema 1.0] or [XML Schema 1.1].
An atomic type is a simple schema type whose {variety}XS11-1 is atomic.
Atomization of a sequence is defined as the result of invoking the fn:data function, as defined in [Functions and Operators 4.0] section 12.1.6 fn:data.
The term available documents refers (TODO: for the time being) to the set of XML documents that an application is able to access by URI.
An axis step is an instance of the production AxisStep: it is an expression that returns a sequence of GNodes that are reachable from a starting GNode via a specified axis. An axis step has three parts: an axis, which defines the direction of movement for the step, a node test, which selects GNodes based on their properties, and zero or more predicates which are used to filter the results.
A base URI declaration specifies the Static Base URI property. The Static Base URI property is used when resolving relative URI references.
In a for clause, when an expression is preceded by the keyword in, the value of that expression is called a binding collection.
In a window clause, when an expression is preceded by the keyword in, the value of that expression is called a binding sequence.
A boundary-space declaration sets the boundary-space policy in the static context, overriding any implementation-defined default. Boundary-space policy controls whether boundary whitespace is preserved by element constructors during processing of the query.
Boundary-space policy. This component controls the processing of boundary whitespace by direct element constructors, as described in 4.12.1.4 Boundary Whitespace.
Boundary whitespace is a sequence of consecutive whitespace characters within the content of a direct element constructor, that is delimited at each end either by the start or end of the content, or by a DirectConstructor, or by an EnclosedExpr. For this purpose, characters generated by character references such as   or by CDataSections are not considered to be whitespace characters.
A character reference is an XML-style reference to a [Unicode] character, identified by its decimal or hexadecimal codepoint.
A choice item type defines an item type that is the union of a number of alternatives. For example the type (xs:hexBinary | xs:base64Binary) defines the union of these two primitive atomic types, while the type (map(*) | array(*)) matches any item that is either a map or an array.
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.
A collation is a specification of the manner in which strings and URIs are compared and, by extension, ordered. For a more complete definition of collation, see [Functions and Operators 4.0] section 5.3 Comparison of strings.
A comma operator is a comma used specifically as the operator in a sequence expression.
A complex terminal is a variable terminal whose production rule references, directly or indirectly, an ordinary production rule.
A computed element constructor creates an element node, allowing both the name and the content of the node to be computed.
When an unprefixed lexical QName is expanded using the constructed element namespace rule, then it uses the namespace URI that is bound to the empty (zero-length) prefix in the statically known namespaces of the static context. If there is no such namespace binding then it uses the no-namespace rule.
A construction declaration sets the construction mode in the static context, overriding any implementation-defined default.
Construction mode. The construction mode governs the behavior of element and document node constructors. If construction mode is preserve, the type of a constructed element node is xs:anyType, and all attribute and element nodes copied during node construction retain their original types. If construction mode is strip, the type of a constructed element node is xs:untyped; all element nodes copied during node construction receive the type xs:untyped, and all attribute nodes copied during node construction receive the type xs:untypedAtomic.
The constructor function for a given simple type is used to convert instances of other simple types into the given type. The semantics of the constructor function call T($arg) are defined to be equivalent to the expression $arg cast as T?.
In an enclosed expression, the optional expression enclosed in curly brackets is called the content expression.
A function definition is said to be context dependent if its result depends on the static or dynamic context of its caller. A function definition may be context-dependent for some arities in its arity range, and context-independent for others: for example fn:name#0 is context-dependent while fn:name#1 is context-independent.
When the context value is a single item, it can also be referred to as the context item; when it is a single node, it can also be referred to as the context node.
The context position is the position of the context value within the series of values currently being processed.
The context size is the number of values in the series of values currently being processed.
The context value is the value currently being processed.
A copy-namespaces declaration sets the value of copy-namespaces mode in the static context, overriding any implementation-defined default. Copy-namespaces mode controls the namespace bindings that are assigned when an existing element node is copied by an element constructor or document constructor.
Copy-namespaces mode. This component controls the in-scope namespaces property that is assigned when an existing element node is copied by an element constructor, as described in 4.12.1 Direct Element Constructors. Its value consists of two parts: preserve or no-preserve, and inherit or no-inherit.
Current dateTime. This information represents an implementation-dependent point in time during the processing of a query , and includes an explicit timezone. It can be retrieved by the fn:current-dateTime function. If called multiple times during the execution of a query , this function always returns the same result.
XQuery 4.0 operates on the abstract, logical structure of an XML document or JSON object rather than its surface syntax. This logical structure, known as the data model, is defined in [XDM 4.0].
A decimal format declaration adds a decimal format to the statically known decimal formats, which define the properties used to format numbers using the fn:format-number() function
decimal-separator(M, R) is used to separate the integer part of the number from the fractional part. The default value for both the marker and the rendition is U+002E (FULL STOP, PERIOD, .) .
When an unprefixed lexical QName is expanded using the annotation namespace rule, then it uses the namespace URI http://www.w3.org/2012/xquery.
Default calendar. This is the calendar used when formatting dates in human-readable output (for example, by the functions fn:format-date and fn:format-dateTime) if no other calendar is requested. The value is a string.
Default collation. This identifies one of the collations in statically known collations as the collation to be used by functions and operators for comparing and ordering values of type xs:string and xs:anyURI (and types derived from them) when no explicit collation is specified.
A default collation declaration sets the value of the default collation in the static context, overriding any implementation-defined default.
Default collection. This is the sequence of items that would result from calling the fn:collection function with no arguments.
When an unprefixed lexical QName is expanded using the default element namespace rule, then it uses the default namespace for elements and types. If this is absent, or if it takes the special value ##any, then the no-namespace rule is used.
Default function namespace. This determines how unprefixed lexical QNames appearing in a static function call or a named function reference are interpreted.
When an unprefixed lexical QName is expanded using the default function namespace rule, the processor searches for a matching function definition as follows: first, if the static context includes a no-namespace function definition with the required local name and arity, then that function definition is used; otherwise, the name is expanded using the default function namespace from the static context.
The default in-scope namespace of an element node
Default language. This is the natural language used when creating human-readable output (for example, by the functions fn:format-date and fn:format-integer) if no other language is requested. The value is a language code as defined by the type xs:language.
Default namespace for elements and types. This is either a namespace URI, or the special value "##any", or absentDM. This indicates how unprefixed QNames are interpreted when they appear in a position where an element name or type name is expected.
Default order for empty sequences. This component controls the processing of empty sequences and NaN values as ordering keys in an order by clause in a FLWOR expression, as described in 4.13.9 Order By Clause.
Default place. This is a geographical location used to identify the place where events happened (or will happen) when processing dates and times using functions such as fn:format-date, fn:format-dateTime, and fn:civil-timezone, if no other place is specified. It is used when translating timezone offsets to civil timezone names, and when using calendars where the translation from ISO dates/times to a local representation is dependent on geographical location. Possible representations of this information are an ISO country code or an Olson timezone name, but implementations are free to use other representations from which the above information can be derived. The only requirement is that it should uniquely identify a civil timezone, which means that country codes for countries with multiple timezones, such as the United States, are inadequate.
When an unprefixed lexical QName is expanded using the default type namespace rule, it uses the default namespace for elements and types. If this is absent, the no-namespace rule is used. If the default namespace for elements and types has the special value ##any, then the lexical QName refers to a name in the namespace http://www.w3.org/2001/XMLSchema.
Default URI collection. This is the sequence of URIs that would result from calling the fn:uri-collection function with no arguments.
The delimiting terminal symbols are: !!=##)$%((#)**:+,--->->...////>::*:::=;<<!--<![CDATA[</<<<=<?==!>=>=?>>>=>>??>?[@[]]]>]```````[`{{{{|||}}`}}×÷AposStringLiteralBracedURILiteralQuotStringLiteralSStringLiteralURIQualifiedName
A variable value (or the context value) depends on another variable value (or the context value) if, during the evaluation of the initializing expression of the former, the latter is accessed through the module context.
A schema typeS1 is said to derive fromschema typeS2 if any of the following conditions is true:
S1 is the same type as S2.
S2 is the base type of S1.
S2 is a pure union type of which S1 is a member type.
There is a schema typeM such that S1derives fromM and Mderives fromS2.
digit(M) is a character used in the picture string to represent an optional digit; the default value is U+0023 (NUMBER SIGN, #) .
A direct element constructor is a form of element constructor in which the name of the constructed element is a constant.
Informally, document order is the order in which nodes appear in the XML serialization of a document.
Dynamically known function definitions. This is a set of function definitions. It includes the statically known function definitions as a subset, but may include other function definitions that are not known statically.
The dynamic context of an expression is defined as information that is needed for the dynamic evaluation of an expression, beyond any information that is needed from the static context.
A dynamic error is an error that must be detected during the dynamic evaluation phase and may be detected during the static analysis phase.
The dynamic evaluation phase is the phase during which the value of an expression is computed.
A dynamic function call is an instance of the construct DynamicFunctionCall: that is, it is an expression in the form E1(E2, E3, ...) in which E1 identifies a function item to be called, and the parenthesized argument list (E2, E3, ...)) identifies the arguments supplied to the function.
Every value matches one or more sequence types. A value is said to have a dynamic typeT if it matches (or is an instance of) the sequence type T.
The effective boolean value of a value is defined as the result of applying the fn:boolean function to the value.
The effective case of a switch expression is the first case clause that matches, using the rules given above, or the default clause if no such case clause exists.
The effective case in a typeswitch expression is the first case clause in which the value of the operand expression matches a SequenceType in the SequenceTypeUnion of the case clause, using the rules of SequenceType matching.
When an unprefixed lexical QName is expanded using the element name matching rule rule, then it uses the default namespace for elements and types. If this is absent, then it uses the no-namespace rule. But if it takes the special value ##any, then the name is taken as matching any expanded QName with the corresponding local part, regardless of namespace: that is, the unprefixed name local is interpreted as *:local.
An empty order declaration sets the default order for empty sequences in the static context, overriding any implementation-defined default. This declaration controls the processing of empty sequences and NaN values as ordering keys in an order by clause in a FLWOR expression.
AThe sequence containing zero items is called anthe empty sequence.
An enclosed expression is an instance of the EnclosedExpr production, which allows an optional expression within curly brackets.
If present, a version declaration may optionally include an encoding declaration. The value of the string literal following the keyword encoding is an encoding name, and must conform to the definition of EncName specified in [XML 1.0] [err:XQST0087]. The purpose of an encoding declaration is to allow the writer of a query to provide a string that indicates how the query is encoded, such as "UTF-8", "UTF-16", or "US-ASCII".
Each key / value pair in a map is called an entry.
An EnumerationType accepts a fixed set of string values.
Environment variables. This is a mapping from names to values. Both the names and the values are strings. The names are compared using an implementation-defined collation, and are unique under this collation. The set of environment variables is implementation-defined and may be empty.
Two tuples T1 and T2 have equivalent grouping keys if and only if, for each grouping variable GV, the atomized value of GV in T1 is deep-equal to the atomized value of GV in T2, as defined by applying the function fn:deep-equal using the appropriate collation.
In addition to its identifying QName, a dynamic error may also carry a descriptive string and one or more additional values called error values.
Executable Base URI. This is an absolute URI used to resolve relative URIs during the evaluation of expressions; it is used, for example, to resolve a relative URI supplied to the fn:doc or fn:unparsed-text functions.
An expanded QName is a triple: its components are a prefix, a local name, and a namespace URI. In the case of a name in no namespace, the namespace URI and prefix are both absent. In the case of a name in the default namespace, the prefix is absent.
exponent-separator(M, R) is used to separate the mantissa from the exponent in scientific notation. The default value for both the marker and the rendition is U+0065 (LATIN SMALL LETTER E, e) .
The expression context for a given expression consists of all the information that can affect the result of the expression.
An extension expression is an expression whose semantics are implementation-defined.
External functions can be characterized as functions that are neither part of the processor implementation, nor written in a language whose semantics are under the control of this family of specifications. The semantics of external functions, including any context dependencies, are entirely implementation-defined. In XSLT, external functions are called 24.1 Extension Functions XT30.
A filter expression is an instance of the construct FilterExpr: that is, it is an expression in the form E1[E2]. Its effect is to return those items from the value of E1 that satisfy the predicate in E2.
A filter expression for maps and arrays is an instance of the construct FilterExprAM: that is, it is an expression in the form E1?[E2]. Its effect is to evaluate E1 to return an array or map, and to select members of the array, or entries from the map, that satisfy the predicate in E2.
A fixed focus is a focus for an expression that is evaluated once, rather than being applied to a series of values; in a fixed focus, the context value is set to one specific value, the context position is 1, and the context size is 1.
The first three components of the dynamic context (context value, context position, and context size) are called the focus of the expression.
A focus function is an inline function expression in which the function signature is implicit: the function takes a single argument of type item()* (that is, any value), and binds this to the context value when evaluating the function body, which returns a result of type item()*.
A function assertion is a predicate that restricts the set of functions matched by a FunctionType. It uses the same syntax as 5.15 Annotations.
Function coercion wraps a function item in a new function whose signature is the same as the expected type. This effectively delays the checking of the argument and return types until the function is called.
A function definition contains information used to evaluate a static function call, including the name, parameters, and return type of the function.
A function item is an item that can be called using a dynamic function call.
A generalized atomic type is an item type whose instances are all atomic items. Generalized atomic types include (a) atomic types, either built-in (for example xs:integer) or imported from a schema, (b) pure union types, either built-in (xs:numeric and xs:error) or imported from a schema, (c) choice item types if their alternatives are all generalized atomic types, and (d) enumeration types.
The term generic node or GNode is a collective term for XNodes (more commonly called simply nodes) representing the parts of an XML document, and JNodes, often used to represent the parts of a JSON document.
A GNode (for generalized node) is either an XNode or a JNode.
The atomized value of a grouping variable is called a grouping key.
grouping-separator(M, R) is used to separate groups of digits (for example as a thousands separator). The default value for both the marker and the rendition is U+002C (COMMA, ,) .
Each grouping specification specifies one grouping variable, which refers to variable bindings in the pre-grouping tuples. The values of the grouping variables are used to assign pre-grouping tuples to groups.
An expression E is said to be guarded by some governing condition C if evaluation of E is not allowed to fail with a dynamic error except when C applies.
Ignorable whitespace consists of any whitespace characters that may occur between terminals, unless these characters occur in the context of a production marked with a ws:explicit annotation, in which case they can occur only where explicitly specified (see A.3.4.2 Explicit Whitespace Handling).
Certain expressions, while not erroneous, are classified as being implausible, because they achieve no useful effect.
Implementation-defined indicates an aspect that may differ between implementations, but must be specified by the implementer for each particular implementation.
Implementation-dependent indicates an aspect that may differ between implementations, is not specified by this or any W3C specification, and is not required to be specified by the implementer for any particular implementation.
Implicit timezone. This is the timezone to be used when a date, time, or dateTime value that does not have a timezone is used in a comparison or arithmetic operation. The implicit timezone is an implementation-defined value of type xs:dayTimeDuration. See 3.2.7.3 Timezones XS1-2 or 3.3.7 dateTime XS11-2 for the range of valid values of a timezone.
infinity(R) is the string used to represent the double value infinity (INF); the default value is the string "Infinity"
In the dynamic context of every module in a query, the context value component must have the same setting. If this shared setting is not absentDM, it is referred to as the initial context value.
If a variable declaration includes an expression (VarValue or VarDefaultValue), the expression is called an initializing expression. The static context for an initializing expression includes all functions, variables, and namespaces that are declared or imported anywhere in the Prolog.
An inline function expression is an instance of the construct InlineFunctionExpr. When evaluated, an inline function expression creates an anonymous function whose properties are defined directly in the inline function expression.
In-scope attribute declarations. Each attribute declaration is identified either by an expanded QName (for a top-level attribute declaration) or by an implementation-dependent attribute identifier (for a local attribute declaration). If the Schema Aware Feature is supported, in-scope attribute declarations include all attribute declarations found in imported schemas.
In-scope element declarations. Each element declaration is identified either by an expanded QName (for a top-level element declaration) or by an implementation-dependent element identifier (for a local element declaration). If the Schema Aware Feature is supported, in-scope element declarations include all element declarations found in imported schemas.
In-scope named item types. This is a mapping from expanded QNames to named item types.
The in-scope namespaces property of an element node is a set of namespace bindings, each of which associates a namespace prefix with a URI.
In-scope schema definitions is a generic term for all the element declarations, attribute declarations, and schema type definitions that are in scope during static analysis of an expression.
In-scope schema types. Each schema type definition is identified either by an expanded QName (for a named type) or by an implementation-dependent type identifier (for an anonymous type). The in-scope schema types include the predefined schema types described in 3.5 Schema Types. If the Schema Aware Feature is supported, in-scope schema types also include all type definitions found in imported schemas.
In-scope variables. This is a mapping from expanded QNames to sequence types. It defines the set of variables that are available for reference within an expression. The expanded QName is the name of the variable, and the type is the static type of the variable.
An item is either an atomic item, a node, or a function item.
An item type is a type that can be expressed using the ItemType syntax, which forms part of the SequenceType syntax. Item types match individual items.
An item type designator is a syntactic construct conforming to the grammar rule ItemType. An item type designator is said to designate an item type.
A JNode is a kind of item used to represent a value within the context of a tree of maps and arrays. A root JNode represents a map or array; a non-root JNode represents a member of an array or an entry in a map.
A JNode (see also [XDM 4.0] section 8.4 JNodes) is an encapsulation of a value as it appears within a tree of maps and arrays, typically (but not necessarily) obtained by parsing JSON texts.
A tree that is rooted at a parentless JNode is referred to as a JTree.
A lexical QName is a name that conforms to the syntax of the QName production
A module that does not contain a Query Body is called a library module. A library module consists of a module declaration followed by a Prolog.
A literal is a direct syntactic representation of an atomic item.
A literal terminal is a token appearing as a string in quotation marks on the right-hand side of an ordinary production rule.
A logical expression is either an and expression or an or expression. If a logical expression does not raise an error, its value is always one of the boolean values true or false.
A lookup expression is an instance of the production LookupExpr: that is, an expression in the form E1?KS, where E1 is an expression returning a sequence of maps or arrays, and KS is a key specifier, which indicates which entries in a map, or members in an array, should be selected.
A main module consists of a Prolog followed by a Query Body.
A map is a function that associates a set of keys with values, resulting in a collection of key / value pairs.
The mapping arrow operator=!> applies a function to each item in a sequence.
MAY means that an item is truly optional.
The values of an array are called its members.
minus-sign(R) is the string used to mark negative numbers; the default value is U+002D (HYPHEN-MINUS, -) .
A module is a fragment of XQuery code that conforms to the Module grammar and can independently undergo the static analysis phase described in 2.4.3 Expression Processing. Each module is either a main module or a library module.
A module declaration serves to identify a module as a library module. A module declaration begins with the keyword module and contains a namespace prefix and a URILiteral.
A module import imports the public variable declarations, public function declarations, and public item type declarations from one or more library modules into the statically known function definitions, in-scope variables, or in-scope named item types of the importing module.
MUST means that the item is an absolute requirement of the specification.
MUST NOT means that the item is an absolute prohibition of the specification.
A named function reference is an instance of the production NamedFunctionRef: it is an expression (written name#arity) which evaluates to a function item, the details of the function item being based on the properties of a function definition in the static context.
A named item type is an ItemType identified by an expanded QName.
When an expression is used to specify the name of a constructed node, that expression is called the name expression of the constructor.
A namespace binding is a pair comprising a namespace prefix (which is either an xs:NCName or empty), and a namespace URI.
A namespace declaration declares a namespace prefix and associates it with a namespace URI, adding the (prefix, URI) pair to the set of statically known namespaces.
A namespace declaration attribute is used inside a direct element constructor. Its purpose is to bind a namespace prefix (including the zero-length prefix) for the constructed element node, including its attributes.
The namespace-sensitive types are xs:QName, xs:NOTATION, types derived by restriction from xs:QName or xs:NOTATION, list types that have a namespace-sensitive item type, and union types with a namespace-sensitive type in their transitive membership.
A node test that consists only of an EQName or a Wildcard is called a name test.
NaN(R) is the string used to represent the double value NaN (not a number); the default value is the string "NaN"
Except where the context indicates otherwise, the term node is used as a synonym for XNode.
A node test is a condition on the properties of a GNode. A node test determines which GNodes returned by an axis are selected by a step.
When an unprefixed lexical QName is expanded using the no-namespace rule, it is interpreted as having an absent namespace URI.
The non-delimiting terminal symbols are: allowingancestorancestor-or-selfandarrayasascendingatattributebase-uriboundary-spacebycasecastcastablecatchchildcollationcommentconstructioncontextcopy-namespacescountdecimal-formatdecimal-separatordeclaredefaultdescendantdescendant-or-selfdescendingdigitdivdocumentdocument-nodeelementelseemptyempty-sequenceencodingendenumeqeveryexceptexponent-separatorexternalfalsefinallyfixedfnfollowingfollowing-or-selffollowing-siblingfollowing-sibling-or-selffollowsfollows-or-isforfunctiongegetgnodegreatestgroupgrouping-separatorgtidivifimportininfinityinheritinstanceintersectisis-notitemjnodekeylaxleleastletltmapmemberminus-signmodmodulenamespacenamespace-nodeNaNnenextno-inheritno-preservenodeofonlyoptionororderorderedorderingotherwiseparentpattern-separatorper-millepercentprecedesprecedes-or-isprecedingpreceding-or-selfpreceding-siblingpreceding-sibling-or-selfpreservepreviousprocessing-instructionrecordreturnsatisfiesschemaschema-attributeschema-elementselfslidingsomestablestartstrictstripswitchtextthentotreattruetrytumblingtypetypeswitchunionunorderedvalidatevaluevariableversionwhenwherewhilewindowxqueryzero-digitBinaryIntegerLiteralDecimalLiteralDoubleLiteralHexIntegerLiteralIntegerLiteralNCNameQName
A construct is said to be a non-trivial instance of a grammatical production if it is not also an instance of one of its sub-productions.
The type xs:numeric is defined as a union type with member types xs:double, xs:float, and xs:decimal. An item that is an instance of any of these types is referred to as a numeric value, and a type that is a subtype of xs:numeric is referred to as a numeric type.
A predicate whose predicate expression returns a value of type xs:numeric+ is called a numeric predicate.
An option declaration declares an option that affects the behavior of a particular implementation. Each option consists of an identifying EQName and a StringLiteral.
An ordinary production rule is a production rule in A.1 EBNF that is not annotated ws:explicit.
An or expression is a non-trivial instance of the production OrExpr.
An output declaration is an option declaration in the namespace http://www.w3.org/2010/xslt-xquery-serialization; it is used to declare serialization parameters.
A static or dynamic function call is a partial function application if one or more arguments is an ArgumentPlaceholder.
A partially applied function is a function created by partial function application.
A path expression is either an absolute path expression or a relative path expression
pattern-separator(M) is a character used to separate positive and negative sub-pictures in a picture string; the default value is U+003B (SEMICOLON, ;) .
percent(M, R) is used to indicate that the number is written as a per-hundred fraction; the default value for both the marker and the rendition is U+0025 (PERCENT SIGN, %) .
per-mille(M, R) is used to indicate that the number is written as a per-thousand fraction; the default value for both the marker and the rendition is U+2030 (PER MILLE SIGN, ‰) .
The pipeline operator-> evaluates an expression and binds the result to the context value before evaluating another expression.
A positional variable is a variable that is preceded by the keyword at.
A pragma is denoted by the delimiters (# and #), and consists of an identifying EQName followed by implementation-defined content.
A predefined entity reference is a short sequence of characters, beginning with an ampersand, that represents a single character that might otherwise have syntactic significance.
The predicate truth value of a value $V is the result of the expression if ($V instance of xs:numeric+) then ($V = position()) else fn:boolean($V).
A primary expression is an instance of the production PrimaryExpr. Primary expressions are the basic primitives of the language. They include literals, variable references, context value references, constructors, and function calls. A primary expression may also be created by enclosing any expression in parentheses, which is sometimes helpful in controlling the precedence of operators.
Every axis has a principal node kind. If an axis can contain elements, then the principal node kind is element; otherwise, it is the kind of nodes that the axis can contain.
A private function is a function with a %private annotation. A private function is hidden from module import, which can not import it into the statically known function definitions of another module.
A private item type is a named item type with a %private annotation. A private item type is hidden from module import, which can not import it into the in-scope named item types of another module.
A private variable is a variable with a %private annotation. A private variable is hidden from module import, which can not import it into the in-scope variables of another module.
A Prolog is a series of declarations and imports that define the processing environment for the module that contains the Prolog.
A public function is a function without a %private annotation. A public function is accessible to module import, which can import it into the statically known function definitions of another module.
A public item type is an item type declaration without a %private annotation. A public item type is accessible to module import, which can import it into the in-scope named item types of another module.
A public variable is a variable without a %private annotation. A public variable is accessible to module import, which can import it into the in-scope variables of another module. Using %public and %private annotations in a main module is not an error, but it does not affect module imports, since a main module cannot be imported. It is a static error [err:XQST0116] if a variable declaration contains both a %private and a %public annotation, more than one %private annotation, or more than one %public annotation.
A pure union type is a simple type that satisfies the following constraints: (a) {variety}XS11-1 is union, (b) the {facets}XS11-1 property is empty, (c) no type in the transitive membership of the union type has {variety}XS11-1list, and (d) no type in the transitive membership of the union type is a type with {variety}XS11-1union having a non-empty {facets}XS11-1 property
A query consists of one or more modules.
The Query Body, if present, consists of an expression that defines the result of the query.
A range expression is a non-trivial instance of the production RangeExpr. A range expression is used to construct a sequence of integers.
A relative path expression is a non-trivial instance of the production RelativePathExpr: it consists of two or more operand expressions separated by / or // operators.
A reserved namespace is a namespace that must not be used in the name of a function declaration.
To resolve a relative URI$rel against a base URI $base is to expand it to an absolute URI, as if by calling the function fn:resolve-uri($rel, $base).
The node ordering that is the reverse of document order is called reverse document order.
Two atomic items K1 and K2 have the same key value if fn:atomic-equal(K1, K2) returns true, as specified in [Functions and Operators 4.0] section 2.2.1 fn:atomic-equal
The Schema Aware Feature permits the query Prolog to contain a schema import, and permits a query to contain a validate expression (see 4.25 Validate Expressions).
A schema import imports the element declarations, attribute declarations, and type definitions from a schema into the in-scope schema definitions. For each named user-defined simple type in the schema, schema import also adds a corresponding constructor function.
A schema type is a complex type or simple type as defined in the [XML Schema 1.0] or [XML Schema 1.1] specifications, including built-in types as well as user-defined types.
A sequence is an ordered collection of zero or more items.
The sequence arrow operator=> applies a function to a supplied sequence.
The sequence concatenation of a number of sequences S1, S2, ... Sn is defined to be the sequence formed from the items of S1, followed by the items from S2, and so on, retaining order.
A sequence expression is a non-trivial instance of the production rule Expr, that is, an expression containing two or more instances of the production ExprSingle separated by the comma operator.
A sequence type is a type that can be expressed using the SequenceType syntax. Sequence types are used whenever it is necessary to refer to a type in an XQuery 4.0 expression. Since all values are sequences, every value matches one or more sequence types.
A sequence type designator is a syntactic construct conforming to the grammar rule SequenceType. A sequence type designator is said to designate a sequence type.
SequenceType matching compares a value with an expected sequence type.
Serialization is the process of converting an XDM instance to a sequence of octets (step DM4 in Figure 1.), as described in [Serialization 4.0].
The Serialization Feature provides means for serializing the result of a query as specified in 2.4.5 Serialization.
Setters are declarations that set the value of some property that affects query processing, such as construction mode or default collation.
SHOULD means that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.
A sequence containing exactly one item is called a singleton.
An enumeration type with a single enumerated value E (such as enum("red")) matches an item S if and only if (a) S is an instance of xs:string, and (b) S is equal to E when compared using Unicode codepoint collation. This is referred to as a singleton enumeration type.
A singleton focus is a fixed focus in which the context value is a singleton item.
Document order is stable, which means that the relative order of two nodes will not change during the processing of a given query , even if this order is implementation-dependent.
Statically known collations. This is an implementation-defined mapping from URI to collation. It defines the names of the collations that are available for use in processing queries and expressions.
Statically known decimal formats. This is a mapping from QNames to decimal formats, with one default format that has no visible name, referred to as the unnamed decimal format. Each format is available for use when formatting numbers using the fn:format-number function.
Statically known function definitions. This is a set of function definitions.
Statically known namespaces. This is a mapping from prefix to namespace URI that defines all the namespaces that are known during static processing of a given expression.
The static analysis phase depends on the expression itself and on the static context. The static analysis phase does not depend on input data (other than schemas).
Static Base URI. This is an absolute URI, used to resolve relative URIs during static analysis.
The static context of an expression is the information that is available during static analysis of the expression, prior to its evaluation.
An error that can be detected during the static analysis phase, and is not a type error, is a static error.
A static function call is an instance of the production FunctionCall: it consists of an EQName followed by a parenthesized list of zero or more arguments.
The static type of an expression is the best inference that the processor is able to make statically about the type of the result of the expression.
The operands of a path expression are conventionally referred to as steps.
A string constructor is an instance of the production StringConstructor: it is an expression that creates a string from literal text and interpolated subexpressions.
The string value of a node is a string and can be extracted by applying the string function to the node.
Two sequence types are deemed to be substantively disjoint if (a) neither is a subtype of the other (see 3.3.1 Subtypes of Sequence Types) and (b) the only values that are instances of both types are one or more of the following:
The empty sequence, ().
The empty mapDM, {}.
The empty arrayDM, [].
Substitution groups are defined in 2.2.2.2 Element Substitution Group XS1-1 and 2.2.2.2 Element Substitution Group XS11-1. Informally, the substitution group headed by a given element (called the head element) consists of the set of elements that can be substituted for the head element without affecting the outcome of schema validation.
Given two sequence types or item types, the rules in this section determine if one is a subtype of the other. If a type A is a subtype of type B, it follows that every value matched by A is also matched by B.
The use of a value that has a dynamic type that is a subtype of the expected type is known as subtype substitution.
Each rule in the grammar defines one symbol, using the following format:
symbol ::= expression
Whitespace and Comments function as symbol separators. For the most part, they are not mentioned in the grammar, and may occur between any two terminal symbols mentioned in the grammar, except where that is forbidden by the /* ws: explicit */ annotation in the EBNF, or by the /* xgc: xml-version */ annotation.
System functions include the functions defined in [Functions and Operators 4.0], functions defined by the specifications of a host language, constructor functions for atomic types, and any additional functions provided by the implementation. System functions are sometimes called built-in functions.
The target namespace of a module is the namespace of the objects (such as elements or functions) that it defines.
A terminal is a symbol or string or pattern that can appear in the right-hand side of a rule, but never appears on the left-hand side in the main grammar, although it may appear on the left-hand side of a rule in the grammar for terminals.
The static context includes a boolean property called trusted that determines whether external resources are available.
A tuple is a set of zero or more named variables, each of which is bound to a value that is an XDM instance.
A tuple stream is an ordered sequence of zero or more tuples.
Each element node and attribute node in an XDM instance has a type annotation (described in [XDM 4.0] section 4.1 Schema Information). The type annotation of a node is a reference to a schema type.
The Typed Data Feature permits an XDM instance to contain element node types other than xs:untyped and attributes node types other than xs:untypedAtomic.
A variable binding may be accompanied by a type declaration, which consists of the keyword as followed by the static type of the variable, declared using the syntax in 3.1 Sequence Types.
The typed value of a node is a sequence of atomic items and can be extracted by applying the data function to the node.
A type error may be raised during the static analysis phase or the dynamic evaluation phase. During the static analysis phase, a type error occurs when the static type of an expression does not match the expected type of the context in which the expression occurs. During the dynamic evaluation phase, a type error occurs when the dynamic type of a value does not match the expected type of the context in which the value occurs.
Within this specification, the term URI refers to a Universal Resource Identifier as defined in [RFC3986] and extended in [RFC3987] with the new name IRI.
User defined functions are functions that contain a function body, which provides the implementation of the function as a content expression.
In the data model, a value is always a sequence.
A variable declaration in the XQuery prolog defines the name and static type of a variable, and optionally a value for the variable. It adds to the in-scope variables in the static context, and may also add to the variable values in the dynamic context.
A variable reference is an EQName preceded by a $-sign.
A variable terminal is an instance of a production rule that is not itself an ordinary production rule but that is named (directly) on the right-hand side of an ordinary production rule.
Variable values. This is a mapping from expanded QNames to values. It contains the same expanded QNames as the in-scope variables in the static context for the expression. The expanded QName is the name of the variable and the value is the dynamic value of the variable, which includes its dynamic type.
A version declaration can identify the applicable XQuery syntax and semantics for a module, as well as its encoding.
In addition to static errors, dynamic errors, and type errors, an XQuery 4.0 implementation may raise warnings, either during the static analysis phase or the dynamic evaluation phase. The circumstances in which warnings are raised, and the ways in which warnings are handled, are implementation-defined.
A whitespace character is any of the characters defined by [http://www.w3.org/TR/REC-xml/#NT-S].
In these rules, if MU and NU are NameTestUnions, then MUwildcard-matchesNU is true if every name that matches MU also matches NU.
A window is a sequence of consecutive items drawn from the binding sequence.
The term XDM instance is used, synonymously with the term value, to denote an unconstrained sequence of items.
An XNode is an instance of one of the node kinds defined in [XDM 4.0] section 7.1 XML Nodes.
XPath 1.0 compatibility mode.This component must be set by all host languages that include XPath 3.1 as a subset, indicating whether rules for compatibility with XPath 1.0 are in effect. XQuery sets the value of this component to false.
An XQuery 1.0 Processor processes a query according to the XQuery 1.0 specification.
An XQuery 3.0 Processor processes a query according to the XQuery 3.0 specification.
An XQuery 3.1 Processor processes a query according to the XQuery 3.1 specification.
An XQuery 4.0 Processor processes a query according to the XQuery 4.0 specification.
An XQuery version number consists of two integers, referred to as the major version number and the minor version number.
xs:anyAtomicType is an atomic type that includes all atomic items (and no values that are not atomic). Its base type is xs:anySimpleType from which all simple types, including atomic, list, and union types, are derived. All primitive atomic types, such as xs:decimal and xs:string, have xs:anyAtomicType as their base type.
xs:dayTimeDuration is derived by restriction from xs:duration. The lexical representation of xs:dayTimeDuration is restricted to contain only day, hour, minute, and second components.
xs:error is a simple type with no value space. It is defined in 3.16.7.3 xs:error XS11-1 and can be used in the 3.1 Sequence Types to raise errors.
xs:untyped is used as the type annotation of an element node that has not been validated, or has been validated in skip mode.
xs:untypedAtomic is an atomic type that is used to denote untyped atomic data, such as text that has not been assigned a more specific type.
xs:yearMonthDuration is derived by restriction from xs:duration. The lexical representation of xs:yearMonthDuration is restricted to contain only year and month components.
A tree that is rooted at a parentless XNode is referred to as an XTree.
zero-digit(M) is the character used in the picture string to represent the digit zero; the default value is U+0030 (DIGIT ZERO, 0) . This character must be a digit (category Nd in the Unicode property database), and it must have the numeric value zero. This property implicitly defines the ten Unicode characters that are used to represent the values 0 to 9 in the function output: Unicode is organized so that each set of decimal digits forms a contiguous block of characters in numerical sequence. Within the picture string any of these ten character can be used (interchangeably) as a place-holder for a mandatory digit. Within the final result string, these ten characters are used to represent the digits zero to nine.
If a section of this specification has been updated since version 3.1, an overview of the changes is provided, along with links to navigate to the next or previous change.
See 1 Introduction
Sections with significant changes are marked with a ✭ symbol in the table of contents.
See 1 Introduction
PR 691 2154
Enumeration types are added as a new kind of ItemType, constraining the value space of strings.
Setting the default namespace for elements and types to the special value ##any causes an unprefixed element name to act as a wildcard, matching by local name regardless of namespace.
The terms FunctionType, ArrayType, MapType, and RecordType replace FunctionTest, ArrayTest, MapTest, and RecordTest, with no change in meaning.
Record types are added as a new kind of ItemType, constraining the value space of maps.
Function coercion now allows a function with arity N to be supplied where a function of arity greater than N is expected. For example this allows the function true#0 to be supplied where a predicate function is required.
The symbols × and ÷ can be used for multiplication and division.
PR 1480 1989
When the element name matches a language keyword such as div or value, it must now be written as a QName literal. This is a backwards incompatible change.
See 4.12.3.1 Computed Element Constructors
When the attribute name matches a language keyword such as by or of, it must now be written as a QName literal. This is a backwards incompatible change.
PR 1513 2028
When the processing instruction name matches a language keyword such as try or validate, it must now be written with a preceding # character. This is a backwards incompatible change.
See 4.12.3.5 Computed Processing Instruction Constructors
When the namespace prefix matches a language keyword such as as or at, it must now be written with a preceding # character. This is a backwards incompatible change.
PR 1763 1830
The syntax on the right-hand side of an arrow operator has been relaxed; a dynamic function call no longer needs to start with a variable reference or a parenthesized expression, it can also be (for example) an inline function expression or a map or array constructor.
The arrow operator => is now complemented by a “mapping arrow” operator =!> which applies the supplied function to each item in the input sequence independently.
All implementations must now predeclare the namespace prefixes math, map, array, and err. In XQuery 3.1 it was permitted but not required to predeclare these namespaces.
PR 2200 2236
The effect of not declaring a default function namespace has changed: user-defined functions can now be in no namespace, and a search for an unprefixed function name will be resolved first against functions in no namespace, and only then against functions in the standard function namespace.
PR 254 2050
The supplied context value is now coerced to the required type specified in the main module using the coercion rules.
Function definitions in the static context may now have optional parameters, provided this does not cause ambiguity across multiple function definitions with the same name. Optional parameters are given a default value, which can be any expression, including one that depends on the context of the caller (so an argument can default to the context value).
PR 682 TODO
The values true() and false() are allowed in function annotations, as well as negated numeric literals and QName literals.
A user-defined function whose name is given as an unprefixed QName is now in no namespace. In previous versions of the language, it represented a name in the default function namespace (which only worked if the default function namespace was explicitly set to an unreserved namespace, which was rarely done because it caused other problems).
PR 1023 1128
It has been clarified that function coercion applies even when the supplied function item matches the required function type. This is to ensure that arguments supplied when calling the function are checked against the signature of the required function type, which might be stricter than the signature of the supplied function item.
A dynamic function call can now be applied to a sequence of functions, and in particular to anthe empty sequence. This makes it easier to chain a sequence of calls.
Parts of the static context that were there purely to assist in static typing, such as the statically known documents, were no longer referenced and have therefore been dropped.
The syntax document-node(N), where N is a NameTestUnion, is introduced as an abbreviation for document-node(element(N)). For example, document-node(*) matches any well-formed XML document (as distinct from a document fragment).
See 3.2.7 Node Types
QName literals are new in 4.0.
Path expressions are extended to handle JNodes (found in trees of maps and arrays) as well as XNodes (found in trees representing parsed XML).
A method call invokes a function held as the value of an entry in a map, supplying the map implicitly as the value of the first argument.
The treat as expression now raises a type error rather than a dynamic error when it fails.
See 4.21.6 Treat
The group is considering removing or substantially changing this feature, it is considered at risk.
PR 159
Keyword arguments are allowed on static function calls, as well as positional arguments.
PR 202
The presentation of the rules for the subtype relationship between sequence types and item types has been substantially rewritten to improve clarity; no change to the semantics is intended.
PR 230
The rules for “errors and optimization” have been tightened up to disallow many cases of optimizations that alter error behavior. In particular there are restrictions on reordering the operands of and and or, and of predicates in filter expressions, in a way that might allow the processor to raise dynamic errors that the author intended to prevent.
PR 254
The term "function conversion rules" used in 3.1 has been replaced by the term "coercion rules".
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.
The value bound to a variable in a let clause is now converted to the declared type by applying the coercion rules.
The coercion rules are now used when binding values to variables (both global variable declarations and local variable bindings). This aligns XQuery with XSLT, and means that the rules for binding to variables are the same as the rules for binding to function parameters.
PR 284
Alternative syntax for conditional expressions is available: if (condition) { X }.
PR 286
Element and attribute tests can include alternative names: element(chapter|section), attribute(role|class).
See 3.2.7 Node Types
The NodeTest in an AxisStep now allows alternatives: ancestor::(section|appendix)
See 3.2.7 Node Types
Element and attribute tests of the form element(N) and attribute(N) now allow N to be any NameTest, including a wildcard.
PR 324
String templates provide a new way of constructing strings: for example `{$greeting}, {$planet}!` is equivalent to $greeting || ', ' || $planet || '!'
PR 326
Support for higher-order functions is now a mandatory feature (in 3.1 it was optional).
See 6 Conformance
PR 344
A for member clause is added to FLWOR expressions to allow iteration over an array.
PR 364
Switch expressions now allow a case clause to match multiple atomic items.
PR 368
The concept of the context item has been generalized, so it is now a context value. That is, it is no longer constrained to be a single item.
PR 433
Numeric literals can now be written in hexadecimal or binary notation; and underscores can be included for readability.
PR 483
The start clause in window expressions has become optional, as well as the when keyword and its associated expression.
PR 487
In XQuery 4.0, an initial set of namespace bindings is prescribed for the static context.
PR 493
A new variable $err:map is available, capturing all error information in one place.
PR 519
The rules for tokenization have been largely rewritten. In some cases the revised specification may affect edge cases that were handled in different ways by different 3.1 processors, which could lead to incompatible behavior.
PR 521
New abbreviated syntax is introduced (focus function) for simple inline functions taking a single argument. An example is fn { ../@code }
PR 587
Switch and typeswitch expressions can now be written with curly brackets, to improve readability.
PR 603
The rules for reporting type errors during static analysis have been changed so that a processor has more freedom to report errors in respect of constructs that are evidently wrong, such as @price/@value, even though dynamic evaluation is defined to return anthe empty sequence rather than an error.
PR 606
Element and attribute tests of the form element(A|B) and attribute(A|B) are now allowed.
PR 635
The rules for the consistency of schemas imported by different query modules, and for consistency between imported schemas and those used for validating input documents, have been defined with greater precision. It is now recognized that these schemas will not always be identical, and that validation with respect to different schemas may produce different outcomes, even if the components of one are a subset of the components of the other.
PR 659
In previous versions the interpretation of location hints in import schema declarations was entirely at the discretion of the processor. To improve interoperability, XQuery 4.0 recommends (but does not mandate) a specific strategy for interpreting these hints.
PR 678
The comparand expression in a switch expression can be omitted, allowing the switch cases to be provided as arbitrary boolean expressions.
PR 728
The syntax record(*) is allowed; it matches any map.
PR 753
The default namespace for elements and types can now be declared to be fixed for a query module, meaning it is unaffected by a namespace declaration appearing on a direct element constructor.
PR 815
The coercion rules now allow conversion in either direction between xs:hexBinary and xs:base64Binary.
PR 820
The value bound to a variable in a for clause is now converted to the declared type by applying the coercion rules.
PR 911
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.
PR 943
A FLWOR expression may now include a while clause, which causes early exit from the iteration when a condition is encountered.
PR 996
The value of a predicate in a filter expression can now be a sequence of integers.
PR 1031
An otherwise operator is introduced: A otherwise B returns the value of A, unless it is anthe empty sequence, in which case it returns the value of B.
PR 1071
In map constructors, the keyword map is now optional, so map { 0: false(), 1: true() } can now be written { 0: false(), 1: true() }, provided it is used in a context where this creates no ambiguity.
PR 1132
Choice item types (an item type allowing a set of alternative item types) are introduced.
PR 1163
Filter expressions for maps and arrays are introduced.
PR 1181
The default namespace for elements and types can be set to the value ##any, allowing unprefixed names in axis steps to match elements with a given local name in any namespace.
If the default namespace for elements and types has the special value ##any, then an unprefixed name in a NameTest acts as a wildcard, matching names in any namespace or none.
The default namespace for elements and types can be set to the value ##any, allowing unprefixed names in axis steps to match elements with a given local name in any namespace.
PR 1197
The keyword fn is allowed as a synonym for function in function types, to align with changes to inline function declarations.
In inline function expressions, the keyword function may be abbreviated as fn.
PR 1212
New keywords introducing item types, such as record, item, and enum, have been added to the list of reserved function names.
PR 1217
Predicates in filter expressions for maps and arrays can now be numeric.
PR 1249
A for key/value clause is added to FLWOR expressions to allow iteration over a map.
PR 1250
Several decimal format properties, including minus sign, exponent separator, percent, and per-mille, can now be rendered as arbitrary strings rather than being confined to a single character.
PR 1254
The rules concerning the interpretation of xsi:schemaLocation and xsi:noNamespaceSchemaLocation attributes have been tightened up.
PR 1265
The rules regarding the document-uri property of nodes returned by the fn:collection function have been relaxed.
PR 1342
The ordered { E } and unordered { E } expressions are retained for backwards compatibility reasons, but in XQuery 4.0 they are deprecated and have no useful effect.
See 4.15 Ordered and Unordered Expressions
The ordering mode declaration is retained for backwards compatibility reasons, but in XQuery 4.0 it is deprecated and has no useful effect.
PR 1344
Parts of the static context that were there purely to assist in static typing, such as the statically known documents, were no longer referenced and have therefore been dropped.
The static typing option has been dropped.
The static typing feature has been dropped.
See 6 Conformance
PR 1361
The term atomic value has been replaced by atomic item.
See 2.1.3 Values
PR 1384
If a type declaration is present, the supplied values in the input sequence are now coerced to the required type. Type declarations are now permitted in XPath as well as XQuery.
PR 1432
In earlier versions, the static context for the initializing expression excluded the variable being declared. This restriction has been lifted.
PR 1470
$err:stack-trace provides information about the current state of execution.
PR 1496
The context value static type, which was there purely to assist in static typing, has been dropped.
PR 1498
The EBNF operators ++ and ** have been introduced, for more concise representation of sequences using a character such as "," as a separator. The notation is borrowed from Invisible XML.
See 2.1 Terminology
The EBNF notation has been extended to allow the constructs (A ++ ",") (one or more occurrences of A, comma-separated, and (A ** ",") (zero or more occurrences of A, comma-separated.
The EBNF operators ++ and ** have been introduced, for more concise representation of sequences using a character such as "," as a separator. The notation is borrowed from Invisible XML.
See A.1 EBNF
See A.1.1 Notation
PR 1501
The coercion rules now apply recursively to the members of an array and the entries in a map.
PR 1532
Four new axes have been defined: preceding-or-self, preceding-sibling-or-self, following-or-self, and following-sibling-or-self.
See 4.6.5.1 Axes
PR 1577
The syntax record() is allowed; the only thing it matches is anthe empty map.
PR 1686
With the pipeline operator ->, the result of an expression can be bound to the context value before evaluating another expression.
PR 1696
Parameter names may be included in a function signature; they are purely documentary.
PR 1703
Ordered maps are introduced.
See 4.14.1 Maps
The order of key-value pairs in the map constructor is now retained in the constructed map.
PR 1874
The coercion rules now reorder the entries in a map when the required type is a record type.
PR 1898
The rules for subtyping of document node types have been refined.
PR 1914
A finally clause can be supplied, which will always be evaluated after the expressions of the try/catch clauses.
PR 1956
Private variables declared in a library module are no longer required to be in the module namespace.
Private functions declared in a library module are no longer required to be in the module namespace.
PR 1982
Whitespace is now required after the opening (# of a pragma. This is an incompatible change, made to ensure that an expression such as error(#err:XPTY0004) can be parsed as a function call taking a QName literal as its argument value.
PR 1991
Named record types used in the signatures of built-in functions are now available as standard in the static context.
PR 2026
The module feature is no longer an optional feature; processing of library modules is now required.
See 6 Conformance
PR 2030
The technical details of how validation works have been moved to the Functions and Operators specification. The XQuery validate expression is now defined in terms of the new xsd-validator function.
PR 2031
The terms XNode and JNode are introduced; the existing term node remains in use as a synonym for XNode where the context does not specify otherwise.
See 2.1.3 Values
JNodes are introduced
PR 2055
Sequences, arrays, and maps can be destructured in a let clause to extract their components into multiple variables.
PR 2094
A general expression is allowed within a map constructor; this facilitates the creation of maps in which the presence or absence of particular keys is decided dynamically.
PR 2115
This section describes and formalizes a convention that was already in use, but not explicitly stated, in earlier versions of the specification.
PR 2130
Operator is-not is introduced, as a complement to the operator is.
Operators precedes and follows are introduced as synonyms for operators << and >>.
PR 2134
The lookup operator ? can now be followed by an arbitrary literal, for cases where keys are items other than integers or NCNames. It can also be followed by a variable reference or a context value reference.
PR 2176
Operators precedes-or-is and follows-or-is are introduced as synonyms for the union of operators << and is and for the union of operators >> and is, respectively.
PR 2202
The type schema-element(N) is now defined to be a subtype of element() and of various other element tests.
See 3.3.2.5.3 Subtyping Nodes: Elements
The type schema-attribute(N) is now defined to be a subtype of attribute() and of various other attribute tests.
PR 2213
This section (“External Resources and Security”) is new.
PR 2218
The rules for value comparisons when comparing values of different types (for example, decimal and double) have changed to be transitive. A decimal value is no longer converted to double, instead the double is converted to a decimal without loss of precision. This may affect compatibility in edge cases involving comparison of values that are numerically very close.
The rules for comparing untyped atomic items with numeric values have changed. Rather than converting an untyped atomic item unconditionally to xs:double, it is now converted to the type of the numeric operand. This is designed to ensure that comparisons such as <a>1.1</a> = 1.1 succeed, given that the values will now be compared as decimals rather than as doubles.
PR 2227
A URIQualifiedName may now supply a prefix as well as a URI and local name.
PR 2236
In the absence of a default namespace declaration, a user-defined function whose name is given as an unprefixed QName is now in no namespace. In previous versions of the language, this would generally be an error.
PR 2256
An ordering is now defined for all data types.
PR 2259
A new parameter canonical is available to give control over serialization of XML, XHTML, and JSON.