This article is part of the [[QueryingXQuery|Query XQuery Portal]].It summarizes provides a summary of the most important features of the upcoming [httphttps://www.w3.org/TR/xquery-30/ XQuery 3.0]and [http://www.w3.org/TR/xpath-30/ XPath 3.0] Recommendationsthat have already been implemented in BaseXRecommendation.
==EQName: Expanded QNames=Enhanced FLWOR Expressions=
A ''QName'' Most clauses of FLWOR expressions can be specified in an arbitrary order: additional {{Code|let}} and {{Code|for}} clauses can now be directly prefixed with its namespace URIput after a {{Code|where}} clause, and multiple {{Code|where}}, which will be enclosed in quotes {{Code|order by}} and followed {{Code|group by }} statements can be used. This means that many nested loops can now be rewritten to a colonsingle FLWOR expression.
'''ExamplesExample:'''* <codepre lang='xquery'><nowiki>"http://www.w3.org/2005/xpath-functions/math"for $country in db:piget('factbook')</nowiki></code> returns the number πcountry* <code>"java:java.io.FileOutputStream":new("output")<where $country/code@population > creates a new Java file output stream100000000 ==Namespace Constructors== New namespaces can now be created via so-called 'Computed Namespace Constructors'. <pre class="brush:xquery"> element node { namespace pref { 'http:for $city in $country//url.org/' } }</precity[population >1000000] ==String Concatenations=group by $name :=$country/name[1]count $idTwo vertical bars return <code>||</code> (also names country id='{ $id }'pipe charactersname='{ $name }') can be used to concatenate strings. This operator is a shortcut for the >{{Mono|ft:contains()$city/name }} function. <pre class="brush:xquery"> 'Hello' || ' ' || 'Universe'</precountry> ==External Variables== Default values can now 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
</pre>
==Group Bygroup by==
FLWOR expressions have been extended to include the [httphttps://www.w3.org/TR/xquery-30/#id-group-by group by] clause, which is well-established among relational database systemsin SQL. <code>group by</code> can be used to apply value-based partitioning to query results:
'''ExampleXQuery:''' <pre classlang="brush:'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) }
</pre>
This query is a rewrite of [httphttps://www.ins.cwi.nl/projects/xmark/Assets/xmlquery.txt Query #20] contained in the [httphttps://www.insprojects.cwi.nl/projectsxmark/xmark XMark Benchmark Suite] to use <code>group by</code>.
The query partitions the customers based on their income.
'''Result:'''
<pre classlang="brush:xml">
<challenge>4731</challenge>
<na>12677</na>
<preferedpreferred>314</preferedpreferred>
<standard>7778</standard>
</pre>
In contrast to the relational GROUP BY statement, the XQuery counterpartconcatenates 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:
<pre classlang="brush:'xquery"'>
...
return element { $income } { $ppl }
</pre>
'''Result:'''
<pre classlang="brush:xml">
<challenge>
<person id="person0">
</pre>
Moreover, a value can be assigned to the grouping variable. This is shown in the following example: '''XQuery:''' <pre lang='xquery'>let $data := <xml> <person country='USA' name='John'/> <person country='USA' name='Jack'/> <person country='Germany' name='Johann'/> </xml>for $person in $data/persongroup by $country := $person/@countryreturn element persons { attribute country { $country }, for $name in $person/@name return element name { data($name) }}</pre> '''Result:'''<pre lang="xml"><persons country="USA"> <name>John</name> <name>Jack</name></persons><persons country="Germany"> <name>Johann</name></persons></pre> ==count== The {{Code|count}} clause enhances the FLWOR expression with a variable that enumerates the iterated tuples. <pre lang='xquery'>for $n in (1 to 10)[. mod 2 = 1]count $creturn <number count="{ $c }" number="{ $n }"/></pre> ==allowing empty== The {{Code|allowing empty}} provides functionality similar to outer joins in SQL: <pre lang='xquery'>for $n allowing empty in ()return 'empty? ' || empty($n)</pre> ==window== Window clauses provide a rich set of variable declarations to process sub-sequences of iterated tuples. An example: <pre lang='xquery'>for tumbling window $w in (2, 4, 6, 8, 10, 12, 14) start at $s when true() only end at $e when $e - $s eq 2return <window>{ $w }</window></pre> More information on window clauses, and all other enhancements, can be found in the [https://www.w3.org/TR/xquery-30/#id-windows 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 lang='xquery'>let $f := function($x, $y) { $x + $y }return $f(17, 25)</pre> '''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:<pre lang='xquery'>let $f := math:pow#2return $f(5, 2)</pre> '''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.<pre lang='xquery'>let $f := substring(?, 1, 3)return ( $f('foo123'), $f('bar456'))</pre> '''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>for-each</code> and <code>fold-left</code> are discussed in more depth on their own Wiki page. =Simple Map Operator= The [https://www.w3.org/TR/xquery-30/#id-map-operator simple map] operator {{Code|!}} 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 lang='xquery'>(: Simple map notation :)(1 to 10) ! element node { . },(: FLWOR notation :)for $i in 1 to 10return element node { $i }</pre> 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 [httphttps://www.w3.org/TR/xquery-30/#id-try-catch try/catch] construct can be used to handle errors at runtime:
'''Example:'''
<pre classlang="brush:'xquery"'>
try {
1 + '2'
} catch err:XPTY0004 {
'Typing error: ' || $err:description
} catch * {
'''Result:''' <code>Typing error: '+' operator: number expected, xs:string found.</code>
==Switch==Within the scope of the catch clause, a number of variables are implicitly declared, giving information about the error that occurred:
* {{Code|$err:code}} error code* {{Code|$err:description}}: error message* {{Code|$err:value}}: value associated with the error (optional)* {{Code|$err:module}}: URI of the module where the error occurred* {{Code|$err:line-number}}: line number where the error occurred* {{Code|$err:column-number}}: column number where the error occurred =Switch= The [httphttps://www.w3.org/TR/xquery-30/#id-switch switch] statement is available in many other programming languages. It chooses one of several expressions to evaluate based on its input value.
'''Example:'''
<pre classlang="brush:'xquery"'>
for $fruit in ("Apple", "Pear", "Peach")
return switch ($fruit)
'''Result:''' <code>red green pink</code>
The expression to evaluate can correspond to multiple input values. '''Example:'''<pre lang='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"</pre>'''Result:''' <code>red red</code> =Function Items=Expanded QNames=
One of the most distinguishing features added in A ''XQuery 3.0'' are ''function itemsQName''can be prefixed with the letter {{Code|Q}}, also known as ''lambdas'' or ''lambda functions''. They make it possible to abstract over functions the namespace URI wrapped in curly braces and thus writing more modular codethe local name.
'''Examples:'''
* <code><nowiki>Q{http://www.w3.org/2005/xpath-functions/math}pi()</nowiki></code> returns the number π
* <code>Q{java:java.io.FileOutputStream}new("output.txt")</code> creates a new Java file output stream
=Namespace Constructors=
New namespaces can be created via so-called 'Computed Namespace Constructors'.
<pre lang='xquery'>
element node { namespace pref { 'http://url.org/' } }
</pre>
Function items =String Concatenations= Two vertical bars <code>||</code> (also named ''pipe characters'') can be obtained in three different ways:used to concatenate strings. This operator is a shortcut for the {{Code|concat()}} function. <pre lang='xquery'> 'Hello' || ' ' || 'Universe'</pre> =External Variables=
<ul><li>Declaring a new ''inline function'':<pre class="brush:xquery">let $f := function($x, $y) { $x + $y }return $f(17, 25)</pre> '''Result:''' <code>42</code></li><li>Getting the function item of an existing (built-in oder user-defined) XQuery function. The arity (number of arguments) has to be specified as there Default values can be more than one function with the same name:<pre class="brush:xquery">let $f := math:pow#2return $f(5, 2)</pre> '''Result:''' <code>25</code></li><li>''Partially applying'' another function or function itemattached to external variable declarations. This is done by supplying only some of the required argumentsway, writing the placeholder <code>?</code> in the positions of the arguments left outan expression can also be evaluated if its external variables have not been bound to a new value. 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'))</pre> '''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 <codepre lang='xquery'>fndeclare variable $user external :map</code> and <code>fn= "admin";"User:fold-left", $user</codepre> are discussed in more depth on their own Wiki page.
==Serialization==
[[Serialization|Serialization ]]parameters can now 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:'''
<pre classlang='xquery'>declare namespace output ="brushhttp://www.w3.org/2010/xslt-xquery-serialization">;
declare option output:omit-xml-declaration "no";
declare option output:method "xhtml";
<<html/>>
</pre>
'''Result:''' <code><?xml version="1.0" encoding="UTF-8"?><html></html></code>
=In BaseX, the {{Code|output}} prefix is statically bound and can thus be omitted. Note that all namespaces need to be specified when using external APIs, such as [http://xqj.net/basex/ XQJ]. =Context Item==
The context item can now be specified in the prolog of an XQuery expressionsexpression:
'''Example:'''
<pre classlang="brush:'xquery"'>declare context item :=document {
<xml>
<text>Hello</text>
<text>World</text>
</xml>};
for $t in .//text()
'''Result:''' <code>5 5</code>
=Annotations=Functions= 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 lang='xquery'>declare %private function local:max($x1, $x2) { if($x1 > $x2) then $x1 else $x2}; local:max(2, 3)</pre>
BaseX supports all functions that have been added in Version 3.0 of the [http://www.w3.org/TR/xpath-functions-30/ XQuery =Functions and Operators] Working Draft. The new functions are listed below:=
* <code>mathThe following functions have been added in the [https:pi()</code>, <code>math:sin()</code>, www.w3.org/TR/xpath-functions-31/ XQuery 3.0 Functions and many others (see [[Math ModuleOperators]])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>for-each</code>, <code>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:map()outermost</code>* , <code>fn:mapparse-pairs()xml</code>* <code>fn:outermost()</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> with 0 arguments* , <code>fn:string-join()</code> with 1 argument* , <code>fn:node-name()</code> with 0 arguments* , <code>fn:round()</code> with 2 arguments* , <code>fn:data()</code> with 0 arguments =Changelog= ;Version 7.7 * Added: [[#Enhanced FLWOR Expressions|Enhanced FLWOR Expressions]] ;Version 7.3 * Added: [[#Simple Map Operator|Simple Map Operator]] ;Version 7.2
=Recent Changes=* Added: [[#Annotations|Annotations]]* Updated: [[#Expanded QNames|Expanded QNames]]
==;Version 7.1==
* Added: [[#Expanded QNames|Expanded QNames]], Computed [[#Namespace Constructors|Namespace ConstructorConstructors]]
==;Version 7.0==
* Added: [[#String ConcatenatorConcatenations|String Concatenations]]
[[Category:XQuery]]