XQuery 3.0

This article is part of the XQuery Portal. It provides a summary of the most important features of the XQuery 3.0 Recommendation.

=Enhanced FLWOR Expressions=

Most clauses of FLWOR expressions can be specified in an arbitrary order: additional let and for clauses can be put after a where clause, and multiple where, order by and group by statements can be used. This means that many nested loops can now be rewritten to a single FLWOR expression.

Example:  for $country in db:open('factbook')//country where $country/@population > 100000000 for $city in $country//city[population > 1000000] group by $name := $country/name[1] count $id return { $city/name }

group by
FLWOR expressions have been extended to include the group by clause, which is well-established in SQL. can be used to apply value-based partitioning to query results:

XQuery:  for $ppl in doc('xmark')//people/person let $ic := $ppl/profile/@income let $income := if($ic < 30000) then "challenge" else if($ic >= 30000 and $ic < 100000) then "standard" else if($ic >= 100000) then "preferred" else "na" group by $income order by $income return element { $income } { count($ppl) }

This query is a rewrite of Query #20 contained in the XMark Benchmark Suite to use. The query partitions the customers based on their income.

Result:  4731 12677 314 7778

In contrast to the relational GROUP BY statement, the XQuery counterpart concatenates the values of all non-grouping variables that belong to a specific group. In the context of our example, all nodes in  that belong to the   partition are concatenated in   after grouping has finished. You can see this effect by changing the return statement to:

 ... return element { $income } { $ppl }

Result:  Kasidit Treweek …  …

Moreover, a value can be assigned to the grouping variable. This is shown in the following example:

XQuery:  let $data :=    for $person in $data/person group by $country := $person/@country/string return element persons { attribute country { $country }, $person/@name ! element name { data } }

Result:   John Jack  Johann

count
The count clause enhances the FLWOR expression with a variable that enumerates the iterated tuples.

<pre class="brush:xquery"> for $n in (1 to 10)[. mod 2 = 1] count $c return &lt;number count="{ $c }" number="{ $n }"/&gt;

allowing empty
The allowing empty provides functionality similar to outer joins in SQL:

<pre class="brush:xquery"> for $n allowing empty in return 'empty? ' || empty($n)

window
Window clauses provide a rich set of variable declarations to process sub-sequences of iterated tuples. An example:

<pre class="brush:xquery"> for tumbling window $w in (2, 4, 6, 8, 10, 12, 14) start at $s when fn:true only end at $e when $e - $s eq 2 return &lt;window&gt;{ $w }&lt;/window&gt;

More information on window clauses, and all other enhancements, can be found in the specification.

=Function Items=

One of the most distinguishing features added in XQuery 3.0 are function items, also known as lambdas or lambda functions. They make it possible to abstract over functions and thus write more modular code.

Examples:

Function items can be obtained in three different ways:

<ul> <li>Declaring a new inline function: <pre class="brush:xquery">let $f := function($x, $y) { $x + $y } return $f(17, 25) Result: </li> <li>Getting the function item of an existing (built-in or user-defined) XQuery function. The arity (number of arguments) has to be specified as there can be more than one function with the same name: <pre class="brush:xquery">let $f := math:pow#2 return $f(5, 2) Result: </li> <li>Partially applying another function or function item. This is done by supplying only some of the required arguments, writing the placeholder  in the positions of the arguments left out. The produced function item has one argument for every placeholder. <pre class="brush:xquery">let $f := fn:substring(?, 1, 3) return ( $f('foo123'),  $f('bar456') ) Result: </li> </ul>

Function items can also be passed as arguments to and returned as results from functions. These so-called Higher-Order Functions like  and   are discussed in more depth on their own Wiki page.

=Simple Map Operator=

The simple map operator ! provides a compact notation for applying the results of a first to a second expression: the resulting items of the first expression are bound to the context item one by one, and the second expression is evaluated for each item. The map operator may be used as replacement for FLWOR expressions:

Example: <pre class="brush:xquery"> (: Simple map notation :) (1 to 10) ! element node {. }, (: FLWOR notation :) for $i in 1 to 10 return element node { $i }

In contrast to path expressions, the results of the map operator will not be made duplicate-free and returned in document order.

=Try/Catch=

The try/catch construct can be used to handle errors at runtime:

Example: <pre class="brush:xquery"> try { 1 + '2' } catch err:XPTY0004 { 'Typing error: ' || $err:description } catch * { 'Error [' || $err:code || ']: ' || $err:description } Result:

Within the scope of the catch clause, a number of variables are implicitly declared, giving information about the error that occurred:


 * $err:code error code
 * $err:description: error message
 * $err:value: value associated with the error (optional)
 * $err:module: URI of the module where the error occurred
 * $err:line-number: line number where the error occurred
 * $err:column-number: column number where the error occurred
 * $err:additional: error stack trace

=Switch=

The switch statement is available in many other programming languages. It chooses one of several expressions to evaluate based on its input value.

Example: <pre class="brush:xquery"> for $fruit in ("Apple", "Pear", "Peach") return switch ($fruit) case "Apple" return "red" case "Pear" return "green" case "Peach" return "pink" default     return "unknown" Result:

The expression to evaluate can correspond to multiple input values.

Example: <pre class="brush:xquery"> for $fruit in ("Apple", "Cherry") return switch ($fruit) case "Apple" case "Cherry" return "red" case "Pear" return "green" case "Peach" return "pink" default return "unknown" Result:

=Expanded QNames=

A QName can be prefixed with the letter "Q" and a namespace URI in the Clark Notation.

Examples:
 * returns the number π
 * creates a new Java file output stream

=Namespace Constructors=

New namespaces can be created via so-called 'Computed Namespace Constructors'.

<pre class="brush:xquery"> element node { namespace pref { 'http://url.org/' } }

=String Concatenations=

Two vertical bars  (also named pipe characters) can be used to concatenate strings. This operator is a shortcut for the fn:concat function.

<pre class="brush:xquery"> 'Hello' || ' ' || 'Universe'

=External Variables=

Default values can be attached to external variable declarations. This way, an expression can also be evaluated if its external variables have not been bound to a new value.

<pre class="brush:xquery"> declare variable $user external := "admin"; "User:", $user

=Serialization=

Serialization parameters can be defined within XQuery expressions. Parameters are placed in the query prolog and need to be specified as option declarations, using the  prefix.

Example: <pre class="brush:xquery"> declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; declare option output:omit-xml-declaration "no"; declare option output:method "xhtml"; &lt;html/&gt; Result:

In BaseX, the output prefix is statically bound and can thus be omitted. Note that all namespaces need to be specified when using external APIs, such as XQJ.

=Context Item=

The context item can be specified in the prolog of an XQuery expression:

Example: <pre class="brush:xquery"> declare context item := document { Hello World };

for $t in .//text return string-length($t) Result:

=Annotations=

XQuery 3.0 introduces annotations to declare properties associated with functions and variables. For instance, a function may be declared %public, %private, or %updating.

Example: <pre class="brush:xquery"> declare %private function local:max($x1, $x2) { if($x1 > $x2) then $x1 else $x2 };

local:max(2, 3)

=Functions=

The following functions have been added in the XQuery 3.0 Functions and Operators Specification:

*,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,  ,

New signatures have been added for the following functions:

,,  ,  ,

=Changelog=


 * Version 8.4


 * Added: %non-deterministic


 * Version 8.0


 * Added: %basex:inline, %basex:lazy


 * Version 7.7


 * Added: Enhanced FLWOR Expressions


 * Version 7.3


 * Added: Simple Map Operator


 * Version 7.2


 * Added: Annotations
 * Updated: Expanded QNames


 * Version 7.1


 * Added: Expanded QNames, Namespace Constructors


 * Version 7.0


 * Added: String Concatenations