'''Example:'''
<syntaxhighlight pre lang="'xquery"'>for $country in db:openget('factbook')//country
where $country/@population > 100000000
for $city in $country//city[population > 1000000]
count $id
return <country id='{ $id }' name='{ $name }'>{ $city/name }</country>
</syntaxhighlightpre>
==group by==
'''XQuery:'''
<syntaxhighlight pre lang="'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) }
</syntaxhighlightpre>
This query is a rewrite of [https://www.ins.cwi.nl/projects/xmark/Assets/xmlquery.txt Query #20] contained in the [https://projects.cwi.nl/xmark/ XMark Benchmark Suite] to use <code>group by</code>.
'''Result:'''
<syntaxhighlight pre lang="xml">
<challenge>4731</challenge>
<na>12677</na>
<preferred>314</preferred>
<standard>7778</standard>
</syntaxhighlightpre>
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 <code>//people/person</code> that belong to the <code>preferred</code> partition are concatenated in <code class="brush:xquery">$ppl</code> after grouping has finished. You can see this effect by changing the return statement to:
<syntaxhighlight pre lang="'xquery"'>
...
return element { $income } { $ppl }
</syntaxhighlightpre>
'''Result:'''
<syntaxhighlight pre lang="xml">
<challenge>
<person id="person0">
…
</challenge>
</syntaxhighlightpre>
Moreover, a value can be assigned to the grouping variable. This is shown in the following example:
'''XQuery:'''
<syntaxhighlight pre lang="'xquery"'>
let $data :=
<xml>
</xml>
for $person in $data/person
group by $country := $person/@country/string()
return element persons {
attribute country { $country },
for $name in $person/@name ! return element name { data($name) }
}
</syntaxhighlightpre>
'''Result:'''
<syntaxhighlight pre lang="xml">
<persons country="USA">
<name>John</name>
<name>Johann</name>
</persons>
</syntaxhighlightpre>
==count==
The {{Code|count}} clause enhances the FLWOR expression with a variable that enumerates the iterated tuples.
<syntaxhighlight pre lang="'xquery"'>
for $n in (1 to 10)[. mod 2 = 1]
count $c
return <number count="{ $c }" number="{ $n }"/>
</syntaxhighlightpre>
==allowing empty==
The {{Code|allowing empty}} provides functionality similar to outer joins in SQL:
<syntaxhighlight pre lang="'xquery"'>
for $n allowing empty in ()
return 'empty? ' || empty($n)
</syntaxhighlightpre>
==window==
Window clauses provide a rich set of variable declarations to process sub-sequences of iterated tuples. An example:
<syntaxhighlight pre lang="'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 <<window>>{ $w }<</window>></syntaxhighlightpre>
More information on window clauses, and all other enhancements, can be found in the [https://www.w3.org/TR/xquery-30/#id-windows specification].
<ul>
<li>Declaring a new ''inline function'':
<syntaxhighlight pre lang="'xquery"'>let $f := function($x, $y) { $x + $y }return $f(17, 25)</syntaxhighlightpre>
'''Result:''' <code>42</code>
</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:
<syntaxhighlight pre lang="'xquery"'>let $f := math:pow#2return $f(5, 2)</syntaxhighlightpre>
'''Result:''' <code>25</code>
</li>
<li>''Partially applying'' another function or function item. This is done by supplying only some of the required arguments, writing the placeholder <code>?</code> in the positions of the arguments left out. The produced function item has one argument for every placeholder.
<syntaxhighlight pre lang="'xquery"'>let $f := fn:substring(?, 1, 3)
return (
$f('foo123'),
$f('bar456')
)</syntaxhighlightpre>
'''Result:''' <code>foo bar</code>
</li>
</ul>
Function items can also be passed as arguments to and returned as results from functions. These so-called [[Higher-Order Functions]] like <code>fn:mapfor-each</code> and <code>fn:fold-left</code> are discussed in more depth on their own Wiki page.
=Simple Map Operator=
'''Example:'''
<syntaxhighlight pre lang="'xquery"'>
(: Simple map notation :)
(1 to 10) ! element node { . },
for $i in 1 to 10
return element node { $i }
</syntaxhighlightpre>
In contrast to path expressions, the results of the map operator will not be made duplicate-free and returned in document order.
'''Example:'''
<syntaxhighlight pre lang="'xquery"'>
try {
1 + '2'
'Error [' || $err:code || ']: ' || $err:description
}
</syntaxhighlightpre>
'''Result:''' <code>Typing error: '+' operator: number expected, xs:string found.</code>
* {{Code|$err:line-number}}: line number where the error occurred
* {{Code|$err:column-number}}: column number where the error occurred
* {{Code|$err:additional}}: error stack trace
=Switch=
'''Example:'''
<syntaxhighlight pre lang="'xquery"'>
for $fruit in ("Apple", "Pear", "Peach")
return switch ($fruit)
case "Peach" return "pink"
default return "unknown"
</syntaxhighlightpre>
'''Result:''' <code>red green pink</code>
'''Example:'''
<syntaxhighlight pre lang="'xquery"'>
for $fruit in ("Apple", "Cherry")
return switch ($fruit)
default
return "unknown"
</syntaxhighlightpre>
'''Result:''' <code>red red</code>
=Expanded QNames=
A ''QName'' can be prefixed with the letter "{{Code|Q" and a }}, the namespace URI wrapped in curly braces and the [http://www.jclark.com/xml/xmlns.htm Clark Notation]local name.
'''Examples:'''
New namespaces can be created via so-called 'Computed Namespace Constructors'.
<syntaxhighlight pre lang="'xquery"'>
element node { namespace pref { 'http://url.org/' } }
</syntaxhighlightpre>
=String Concatenations=
Two vertical bars <code>||</code> (also named ''pipe characters'') can be used to concatenate strings. This operator is a shortcut for the {{Code|fn:concat()}} function.
<syntaxhighlight pre lang="'xquery"'>
'Hello' || ' ' || 'Universe'
</syntaxhighlightpre>
=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.
<syntaxhighlight pre lang="'xquery"'>
declare variable $user external := "admin";
"User:", $user
</syntaxhighlightpre>
=Serialization=
[[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 <code>output</code> prefix.
'''Example:'''
<syntaxhighlight pre lang="'xquery"'>
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:omit-xml-declaration "no";
declare option output:method "xhtml";
<html/>
</syntaxhighlightpre>
'''Result:''' <code><?xml version="1.0" encoding="UTF-8"?><html></html></code>
'''Example:'''
<syntaxhighlight pre lang="'xquery"'>
declare context item := document {
<xml>
for $t in .//text()
return string-length($t)
</syntaxhighlightpre>
'''Result:''' <code>5 5</code>
'''Example:'''
<syntaxhighlight pre lang="'xquery"'>
declare %private function local:max($x1, $x2) {
if($x1 > $x2) then $x1 else $x2
local:max(2, 3)
</syntaxhighlightpre>
=Functions=
The following functions have been added in the [https://www.w3.org/TR/xpath-functions-31/ XQuery 3.0 Functions and Operators] Specification:
<code>fn:analyze-string</code>* , <code>fn:available-environment-variables</code>, <code>fn:element-with-id</code>, <code>fn:environment-variable</code>, <code>fn:filter</code>, <code>fn:fold-left</code>, <code>fn:fold-right</code>, <code>fn:for-each</code>, <code>fn:for-each-pair</code>, <code>fn:format-date</code>, <code>fn:format-dateTime</code>, <code>fn:format-integer</code>, <code>fn:format-number</code>, <code>fn:format-time</code>, <code>fn:function-arity</code>, <code>fn:function-lookup</code>, <code>fn:function-name</code>, <code>fn:generate-id</code>, <code>fn:has-children</code>, <code>fn:head</code>, <code>fn:innermost</code>, <code>fn:outermost</code>, <code>fn:parse-xml</code>, <code>fn:parse-xml-fragment</code>, <code>fn:path</code>, <code>fn:serialize</code>, <code>fn:tail</code>, <code>fn:unparsed-text</code>, <code>fn:unparsed-text-available</code>, <code>fn:unparsed-text-lines</code>, <code>fn:uri-collection</code>
New signatures have been added for the following functions:
<code>fn:document-uri</code>, <code>fn:string-join</code>, <code>fn:node-name</code>, <code>fn:round</code>, <code>fn:data</code>
=Changelog=
;Version 8.4
* Added: %non-deterministic
;Version 8.0
* Added: %basex:inline, %basex:lazy
;Version 7.7