View Old View New View Both View Only Previous Next

This draft contains only sections that have differences from the version that it modified.

W3C

XQuery 4.0: An XML Query Language

W3C Editor's Draft 23 February 2026

This version:
https://qt4cg.org/specifications/xquery-40/
Most recent version of XQuery:
https://qt4cg.org/specifications/xquery-40/
Most recent Recommendation of XQuery:
https://www.w3.org/TR/2017/REC-xquery-31-20170321/
Editor:
Michael Kay, Saxonica <http://www.saxonica.com/>

This document is also available in these non-normative formats: XML.


Abstract

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.

Status of this Document

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.

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.

Dedication

The publications of this community group are dedicated to our co-chair, Michael Sperberg-McQueen (1954–2024).


4 Expressions

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
| QuantifiedExpr
| SwitchExpr
| TypeswitchExpr
| IfExpr
| TryCatchExpr
| OrExpr
ExprSingle::=FLWORExpr
| QuantifiedExpr
| SwitchExpr
| TypeswitchExpr
| IfExpr
| TryCatchExpr
| OrExpr
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.

4.6 Path Expressions

Changes in 4.0 (next | previous)

  1. 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
| RelativePathExpr
/* 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: 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.

4.6.1 Absolute Path Expressions

The expression consisting of / on its own is treated as an abbreviation for the path expression/..

An expression of the form /PP (that is, a path expression with a leading /) is treated as an abbreviation for the expression self::gnode()/(fn:root(.) treat as (document-node()|jnode())/PP. The effect of this expansion is that for every item J in the context value V:

  1. A type error occurs if J is not a GNode [err:XPTY0020].

  2. The root GNode R of the GTree containing J is selected.

  3. A type error occurs if R is neither a JNode nor a document node [err:XPDY0050].

  4. The expression that follows the leading / is evaluated with R as the context value.

Note:

If the context value includes a map or array, it is not converted implicitly to a JNode; rather, a type error occurs.

The results of these multiple evaluations are then combined into a single sequence; if the result is a set of GNodes, the GNodes are delivered in document order with duplicates eliminated.

Note:

The / character can be used either as a complete expression or as the beginning of a longer path expression such as /*. Also, * is both the multiply operator and a wildcard in path expressions. This can cause parsing difficulties when / appears on the left-hand side of *. This is resolved using the leading-lone-slash constraint. For example, /* and / * are valid path expressions containing wildcards, but /*5 and / * 5 raise syntax errors. Parentheses must be used when / is used on the left-hand side of an operator that could be confused with a node test, as in (/) * 5. Similarly, 4 + / * 5 raises a syntax error, but 4 + (/) * 5 is a valid expression. The expression 4 + / is also valid, because / does not occur on the left-hand side of the operator.

Similarly, in the expression / union /*, union is interpreted as an element name rather than an operator. For it to be parsed as an operator, the expression should be written (/) union /*.

An expression of the form //PP (that is, an absolute path expression with a leading //) is treated as an abbreviation for the expression self::gnode()/(fn:root(.) treat as (document-node()|jnode())/descendant-or-self::gnode()/PP. The effect of this expansion is that for every item J in the context value V:

  1. A type error occurs if J is not a GNode [err:XPTY0020].

  2. The root GNode R of the GTree containing J is selected.

  3. A type error occurs if R is neither a JNode nor a document node [err:XPDY0050].

  4. The descendants of R are selected, along with R itself.

  5. For every GNode D in this set of GNodes, the expression that follows the leading // is evaluated with D as the context value.

The results of these multiple evaluations are then combined into a single sequence; if the result is a set of GNodes, the GNodes are delivered in document order with duplicates eliminated.

Any map or array that is present in the context value is first coerced to a JNode by applying the fn:jtree function.

If (after this coercion) the context value is not a sequence of GNodes, a type error is raised [err:XPTY0020]. At evaluation time, if the root GNode of any item in the context value is not a document node or a JNode, a type error is raised [err:XPDY0050].

Note:

The descendants of an XNode do not include attribute nodes. However, the rules for expanding // ensure that .//@* selects all attributes of all descendants

Note:

// on its own is not a valid expression.