Please check the errata for any errors or issues reported since publication.
See also translations.
This document is also available in these non-normative formats: XML.
Copyright © 2000 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
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 is a draft prepared by the QT4CG (officially registered in W3C as the XSLT Extensions Community Group). Comments are invited.
The publications of this community group are dedicated to our co-chair, Michael Sperberg-McQueen (1954–2024).
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.]
[Definition: A namespace binding is a pair comprising a namespace prefix (which is either an xs:NCName or empty), and a namespace URI.]
Element nodes have a property called in-scope namespaces. [Definition: 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.] For a given element, one namespace binding may have an empty prefix; the URI of this namespace binding is referred to as the default in-scope namespace for the element.
Note:
In [XML Path Language (XPath) Version 1.0], the in-scope namespaces of an element node are represented by a collection of namespace nodes arranged on a namespace axis, which is optional and deprecated in [XPath 4.0]. XQuery does not support the namespace axis and does not represent namespace bindings in the form of nodes.
However, where other specifications such as [XSLT and XQuery Serialization 4.0] refer to namespace nodes, these nodes may be synthesized from the in-scope namespaces of an element node by interpreting each namespace binding as a namespace node. An application that needs to create a set of namespace nodes to represent these bindings for an element bound to $e can do so using the following code.
in-scope-prefixes($e) ! namespace {.}{ namespace-uri-for-prefix(., $e)}for key $k value $v in in-scope-namespaces($e)
return namespace {$k}{$v}[Definition: The default in-scope namespace of an element node] is the namespace URI to which the empty prefix is bound in the element’s in-scope namespaces. In the absence of an explicit binding for the empty prefix, the default in-scope namespace is absentDM.
[Definition: 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.] When comparing two expanded QNames, the prefixes are ignored: the local name parts must be equal under the Unicode codepoint collation (Section 5.3.1 CollationsFO), and the namespace URI parts must either both be absent, or must be equal under the Unicode codepoint collation.
Note:
The datumDM of an atomic item of type xs:QName is an expanded QName. However, the term expanded QName is also used for the names of constructs such as functions, variables, and types that are not themselves atomic items.
In the XQuery 4.0 grammar, QNames representing the names of elements, attributes, functions, variables, types, or other such constructs are written as instances of the grammatical production EQName.
EQName | ::= | QName | URIQualifiedName |
URIQualifiedName | ::= | BracedURILiteralNCName |
| /* ws: explicit */ | ||
BracedURILiteral | ::= | "Q" "{" (PredefinedEntityRef | CharRef | [^&{}])* "}" |
| /* ws: explicit */ |
The EQName production allows a QName to be written in one of three ways:
local-name only (for example, invoice).
A name written in this form has no prefix, and the rules for determining the namespace depend on the context in which the name appears: the various rules used are summarized in 2.1.4 Expanding Lexical QNames. This form is a lexical QName.
prefix plus local-name (for example, my:invoice).
In this case the prefix and local name of the QName are as written, and the namespace URI is inferred from the prefix by examining the statically known namespaces in the static context where the QName appears; the context must include a binding for the prefix. This form is a lexical QName.
URI plus local-name (for example, Q{http://example.com/ns}invoice).
In this case the local name and namespace URI are as written, and the prefix is absent. This way of writing a QName is context-free, which makes it particularly suitable for use in queries that are generated by software. This form is a URIQualifiedName. If the BracedURILiteral has no content (for example, Q{}invoice) then the namespace URI of the QName is absent.
[Definition: A lexical QName is a name that conforms to the syntax of the QName production].
The namespace URI value in a URIQualifiedName is whitespace normalized according to the rules for the xs:anyURI type in Section 3.2.17 anyURI XS1-2 or Section 3.3.17 anyURI XS11-2. It is a static error [err:XQST0070] if the namespace URI for an EQName is http://www.w3.org/2000/xmlns/.
Here are some examples of EQNames:
pi is a lexical QName without a namespace prefix.
math:pi is a lexical QName with a namespace prefix.
Q{http://www.w3.org/2005/xpath-functions/math}pi specifies the namespace URI using a BracedURILiteral; it is not a lexical QName.
This document uses the following namespace prefixes to represent the namespace URIs with which they are listed. Although these prefixes are used within this specification to refer to the corresponding namespaces, not all of these bindings will necessarily be present in the static context of every expression, and authors are free to use different prefixes for these namespaces, or to bind these prefixes to different namespaces.
xml: http://www.w3.org/XML/1998/namespace
xs: http://www.w3.org/2001/XMLSchema
xsi: http://www.w3.org/2001/XMLSchema-instance
fn: http://www.w3.org/2005/xpath-functions
array: http://www.w3.org/2005/xpath-functions/array
map: http://www.w3.org/2005/xpath-functions/map
math: http://www.w3.org/2005/xpath-functions/math
err: http://www.w3.org/2005/xqt-errors (see 2.4.2 Identifying and Reporting Errors).
local: http://www.w3.org/2005/xquery-local-functions (see 5.18 Function Declarations.)
output: http://www.w3.org/2010/xslt-xquery-serialization
xq: http://www.w3.org/2012/xquery
[Definition: 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.] The term URI has been retained in preference to IRI to avoid introducing new names for concepts such as “Base URI” that are defined or referenced across the whole family of XML specifications.
Note:
In most contexts, processors are not required to raise errors if a URI is not lexically valid according to [RFC3986] and [RFC3987]. See 2.5.5 URI Literalsand 4.12.1.2 Namespace Declaration Attributes for details.
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.
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.
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 to use quotation marks (for example element "div") when the node name is a simple NCName. 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 {}
A QName literal written as an unprefixed lexical QName (the first form above) is resolved using the element constructor namespace rule (TODO: add link, this is defined in PR 1987). This differs from the normal rules for evaluating a QName literal as an atomic item of type xs:QName.
Note that the last two 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 {}
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 with a prefix, it is expanded using the constructed element namespace rule.
If the value is a URI-qualified name (Q{uri}local), it is converted to an expanded QName with the supplied namespace URI and local name, and with no prefix.
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 an 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.5.6 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>
CompNamespaceConstructor | ::= | "namespace" CompNodeNCNameEnclosedExpr |
CompNodeNCName | ::= | StringLiteral | UnreservedNCName | ("{" Expr "}") |
StringLiteral | ::= | AposStringLiteral | QuotStringLiteral |
| /* ws: explicit */ | ||
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 a string literal, for example namespace "xlink" { "http://www.w3.org/1999/xlink" }. The content of the string literal must either take the form of an NCName, or must be a zero-length string.
As a simple NCName, 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 an 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 an 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 in-scopethe in-scope namespacesnamespaces of any element, but if an element constructor’s content sequence contains a namespace node, the namespace binding it represents is added to thethat element’s in-scope namespaces.
A computed namespace constructor has no effect on the staticallystatically known namespaces known namespacesin 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 an 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>A query can be assembled from one or more fragments called modules. [Definition: 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.3.3 Expression Processing. Each module is either a main module or a library module.]
[Definition: A main module consists of a Prolog followed by a Query Body.] A query has exactly one main module. In a main module, the Query Body is evaluated with respect to the static and dynamic contexts of the main module in which it is found, and its value is the result of the query.
[Definition: 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 library module cannot be evaluated directly; instead, it provides function and variable declarations that can be imported into other modules.
The XQuery syntax does not allow a module to contain both a module declaration and a Query Body.
[Definition: A Prolog is a series of declarations and imports that define the processing environment for the module that contains the Prolog.] Each declaration or import is followed by a semicolon. A Prolog is organized into two parts.
The first part of the Prolog consists of setters, imports, namespace declarations, and default namespace declarations. [Definition: Setters are declarations that set the value of some property that affects query processing, such as construction mode or default collation.] Namespace declarations and default namespace declarations affect the interpretation of lexical QNames within the query. Imports are used to import definitions from schemas and modules. [Definition: The target namespace of a module is the namespace of the objects (such as elements or functions) that it defines. ]
The second part of the Prolog consists of declarations of variables, functions, and options. These declarations appear at the end of the Prolog because they may be affected by declarations and imports in the first part of the Prolog.
[Definition: The Query Body, if present, consists of an expression that defines the result of the query.] Evaluation of expressions is described in 4 Expressions. A module can be evaluated only if it has a Query Body.
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).
In addition to the system functions, XQuery allows users to declare functions of their own. A function declaration declares a family of functions having the same name and similar parameters. The declaration specifies the name of the function, the names and datatypes of the parameters, and the datatype of the result. All datatypes are specified using the syntax described in 3 Types.
Including a function declaration in the query causes a corresponding function definition to be added to the statically known function definitions of the static context. The associated functions also become available in the dynamically known function definitions of the dynamic context.
FunctionDecl | ::= | "declare" Annotation* "function" EQName "(" ParamListWithDefaults? ")" TypeDeclaration? (FunctionBody | "external") |
| /* xgc: reserved-function-names */ | ||
Annotation | ::= | "%" EQName ("(" (AnnotationValue ++ ",") ")")? |
EQName | ::= | QName | URIQualifiedName |
ParamListWithDefaults | ::= | (ParamWithDefault ++ ",") |
ParamWithDefault | ::= | VarNameAndType (":=" ExprSingle)? |
VarNameAndType | ::= | "$" EQNameTypeDeclaration? |
TypeDeclaration | ::= | "as" SequenceType |
SequenceType | ::= | ("empty-sequence" "(" ")") |
ExprSingle | ::= | FLWORExpr |
FunctionBody | ::= | EnclosedExpr |
EnclosedExpr | ::= | "{" Expr? "}" |
A function declaration specifies whether the implementation of the function is user-defined or external.
In addition to user-defined functions and external functions, XQuery 4.0 allows anonymous functions to be declared in the body of a query using inline function expressions.
The following example illustrates the declaration and use of a local function that accepts a sequence of employee elements, summarizes them by department, and returns a sequence of dept elements.
declare function local:summary($emps as element(employee)*) as element(dept)* {
for $no in distinct-values($emps/deptno)
let $emp := $emps[deptno = $no]
return <dept>
<deptno>{ $no }</deptno>
<headcount>{ count($emp) }</headcount>
<payroll>{ sum($emp/salary) }</payroll>
</dept>
};
local:summary(doc("acme_corp.xml")//employee[location = "Denver"])Every declared function must be in a namespace; that is, every declared function name must (when expanded) have a non-null namespace URI [err:XQST0060].
A public function declared in a library module must be in the target namespace of the library module [err:XQST0048].
[Definition: A reserved namespace is a namespace that must not be used in the name of a function declaration.] It is a static error [err:XQST0045] if the function name in a function declaration (when expanded) is in a reserved namespace. The following namespaces are reserved namespaces:
http://www.w3.org/XML/1998/namespace
http://www.w3.org/2001/XMLSchema
http://www.w3.org/2001/XMLSchema-instance
http://www.w3.org/2005/xpath-functions
http://www.w3.org/2005/xpath-functions/array
http://www.w3.org/2005/xpath-functions/map
http://www.w3.org/2005/xpath-functions/math
http://www.w3.org/2012/xquery
If the function name in a function declaration has no namespace prefix, it is considered to be in the default function namespace. This will result in a static error if the default function namespace is a reserved namespacesnamespace.
In order to allow modules to declare functions for local use within the module without defining a new namespace, XQuery predefines the namespace prefix local to the namespace http://www.w3.org/2005/xquery-local-functions. It is suggested (but not required) that this namespace be used for defining local functions, including private functions declared in library modules.
[Definition: An option declaration declares an option that affects the behavior of a particular implementation. Each option consists of an identifying EQName and a StringLiteral.]
OptionDecl | ::= | "declare" "option" EQNameStringLiteral |
EQName | ::= | QName | URIQualifiedName |
StringLiteral | ::= | AposStringLiteral | QuotStringLiteral |
| /* ws: explicit */ |
Typically, a particular option will be recognized by some implementations and not by others. The syntax is designed so that option declarations can be successfully parsed by all implementations.
If the EQName of an option is a lexical QName then it is expanded using the default annotation namespace rule.
Note:
If the name is unprefixed, the expanded QName will be in the http://www.w3.org/2012/xquery namespace, which is reserved for option declarations defined by the XQuery family of specifications. XQuery does not currently define declaration options in this namespace.
Each implementation recognizes the http://www.w3.org/2012/xquery namespace URI and and all options defined in this namespace in this specification. In addition, each implementation recognizes an implementation-defined set of namespace URIs and an implementation-defined set of option names defined in those namespaces. If the namespace part of an option declaration's name is not recognized, the option declaration is ignored.
Otherwise, the effect of the option declaration, including its error behavior, is implementation-defined. For example, if the local part of the QName is not recognized, or if the StringLiteral does not conform to the rules defined by the implementation for the particular option declaration, the implementation may choose whether to raise an error, ignore the option declaration, or take some other action.
Implementations may impose rules on where particular option declarations may appear relative to variable declarations and function declarations, and the interpretation of an option declaration may depend on its position.
An option declaration must not be used to change the syntax accepted by the processor, or to suppress the detection of static errors. However, it may be used without restriction to modify the semantics of the query. The scope of the option declaration is implementation-defined—for example, an option declaration might apply to the whole query, to the current module, or to the immediately following function declaration.
The following examples illustrate several possible uses for option declarations:
This option declaration might be used to specify how comments in source documents returned by the fn:doc() function should be handled:
declare option exq:strip-comments "true";
This option declaration might be used to associate a namespace used in function names with a Java class:
declare namespace smath = "http://example.org/MathLibrary"; declare option exq:java-class "smath = java.lang.StrictMath";