Difference between revisions of "XQuery 3.1"

From BaseX Documentation
Jump to navigation Jump to search
m (Text replacement - "[http://en.wikipedia.org/" to "[https://en.wikipedia.org/")
(26 intermediate revisions by 3 users not shown)
Line 1: Line 1:
This article is part of the [[XQuery|XQuery Portal]].
+
This article is part of the [[XQuery|XQuery Portal]]. It provides a summary of the most important features of the [https://www.w3.org/TR/xquery-31/ XQuery 3.1] Recommendation.
It summarizes the new features of the [http://www.w3.org/TR/xquery-31/ XQuery 3.1] and
 
[http://www.w3.org/TR/xpath-functions-31/ XQuery 3.1 Functions and Operators] specifications
 
that are already supported by BaseX.
 
 
 
Please note that not all of the features that are listed on this page are already
 
found in the official specification documents today. You can check out the
 
[https://www.w3.org/Bugs/Public/ W3 Bugzilla Tracker] to find out more about the
 
most recently added features.
 
  
 
=Maps=
 
=Maps=
Line 15: Line 7:
 
Maps can be constructed as follows:
 
Maps can be constructed as follows:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 
map { },                                    (: empty map :)
 
map { },                                    (: empty map :)
 
map { 'key': true(), 1984: (<a/>, <b/>) },  (: map with two entries :)
 
map { 'key': true(), 1984: (<a/>, <b/>) },  (: map with two entries :)
Line 22: Line 14:
 
   return map { $i: 'value' || $i }
 
   return map { $i: 'value' || $i }
 
)
 
)
</pre>
+
</syntaxhighlight>
  
The function corresponding to the map has the signature {{Code|function($key as xs:anyAtomicType) as item()*}}. The expression {{Code|$map($key)}} returns the associated value; the function call {{Code|map:get($map, $key)}} is equivalent. For example, if {{Code|$books-by-isbn}} is a map whose keys are ISBNs and whose associated values are {{Code|book}} elements, then the expression {{Code|$books-by-isbn("0470192747")}} returns the {{Code|book}} element with the given ISBN. The fact that a map is a function item allows it to be passed as an argument to higher-order functions that expect a function item as one of their arguments. As an example, the following query uses the higher-order function {{Code|fn:map($f, $seq)}} to extract all bound values from a map:
+
The function corresponding to the map has the signature {{Code|function($key as xs:anyAtomicType) as item()*}}. The expression {{Code|$map($key)}} returns the associated value; the function call {{Code|map:get($map, $key)}} is equivalent. For example, if {{Code|$books-by-isbn}} is a map whose keys are ISBNs and whose associated values are {{Code|book}} elements, then the expression {{Code|$books-by-isbn("0470192747")}} returns the {{Code|book}} element with the given ISBN. The fact that a map is a function item allows it to be passed as an argument to [[Higher-Order Functions]] that expect a function item as one of their arguments. As an example, the following query uses the higher-order function {{Code|fn:map($f, $seq)}} to extract all bound values from a map:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 
let $map := map { 'foo': 42, 'bar': 'baz', 123: 456 }
 
let $map := map { 'foo': 42, 'bar': 'baz', 123: 456 }
 
return fn:for-each(map:keys($map), $map)
 
return fn:for-each(map:keys($map), $map)
</pre>
+
</syntaxhighlight>
  
 
This returns some permutation of {{Code|(42, 'baz', 456)}}.
 
This returns some permutation of {{Code|(42, 'baz', 456)}}.
Line 41: Line 33:
 
=Arrays=
 
=Arrays=
  
An ''array'' is a function that associates a set of positions, represented as positive integer keys, with values. The first position in an array is associated with the integer {{Code|1}}. The values of an array are called its members. In the type hierarchy, array has a distinct type, which is derived from function. In BaseX, arrays (as well as sequences) are based on an efficient [http://en.wikipedia.org/wiki/Finger_tree Finger Tree] implementation.
+
An ''array'' is a function that associates a set of positions, represented as positive integer keys, with values. The first position in an array is associated with the integer {{Code|1}}. The values of an array are called its members. In the type hierarchy, array has a distinct type, which is derived from function. In BaseX, arrays (as well as sequences) are based on an efficient [https://en.wikipedia.org/wiki/Finger_tree Finger Tree] implementation.
  
 
Arrays can be constructed in two ways. With the square bracket notation, the comma serves as delimiter:
 
Arrays can be constructed in two ways. With the square bracket notation, the comma serves as delimiter:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
[],            (: empty array :)
 
[],            (: empty array :)
 
[ (1, 2) ],    (: array with single member :)
 
[ (1, 2) ],    (: array with single member :)
 
[ 1 to 2, 3 ]  (: array with two members; same as: [ (1, 2), 3 ] :)
 
[ 1 to 2, 3 ]  (: array with two members; same as: [ (1, 2), 3 ] :)
</pre>
+
</syntaxhighlight>
  
 
With the {{Code|array}} keyword and curly brackets, the inner expression is evaluated as usual, and the resulting values will be the members of the array:
 
With the {{Code|array}} keyword and curly brackets, the inner expression is evaluated as usual, and the resulting values will be the members of the array:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
array { },          (: empty array;              same as: array { () } :)   
 
array { },          (: empty array;              same as: array { () } :)   
 
array { (1, 2) },    (: array with two members;  same as: array { 1, 2 } :)
 
array { (1, 2) },    (: array with two members;  same as: array { 1, 2 } :)
 
array { 1 to 2, 3 }  (: array with three members; same as: array { 1, 2, 3 } :)
 
array { 1 to 2, 3 }  (: array with three members; same as: array { 1, 2, 3 } :)
</pre>
+
</syntaxhighlight>
  
 
The function corresponding to the array has the signature {{Code|function($index as xs:integer) as item()*}}. The expression {{Code|$array($index)}} returns an addressed member of the array. The following query returns the five array members {{Code|48 49 50 51 52}} as result:
 
The function corresponding to the array has the signature {{Code|function($index as xs:integer) as item()*}}. The expression {{Code|$array($index)}} returns an addressed member of the array. The following query returns the five array members {{Code|48 49 50 51 52}} as result:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
let $array := array { 48 to 52 }
 
let $array := array { 48 to 52 }
 
for $i in 1 to array:size($array)
 
for $i in 1 to array:size($array)
 
return $array($i)
 
return $array($i)
</pre>
+
</syntaxhighlight>
  
 
Like all other values, arrays are immutable. For example, the <code>[[Array Module#array:reverse|array:reverse]]</code> function creates a new array containing a re-ordering of the members of an existing array, but the existing array is not changed by the operation. Like sequences, arrays have no identity. It is meaningful to compare the contents of two arrays, but there is no way of asking whether they are "the same array": two arrays with the same content are indistinguishable.
 
Like all other values, arrays are immutable. For example, the <code>[[Array Module#array:reverse|array:reverse]]</code> function creates a new array containing a re-ordering of the members of an existing array, but the existing array is not changed by the operation. Like sequences, arrays have no identity. It is meaningful to compare the contents of two arrays, but there is no way of asking whether they are "the same array": two arrays with the same content are indistinguishable.
Line 73: Line 68:
 
If an array is ''atomized'', all of its members will be atomized. As a result, an atomized item may now result in more than one item. Some examples:
 
If an array is ''atomized'', all of its members will be atomized. As a result, an atomized item may now result in more than one item. Some examples:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
fn:data([1 to 2])        (: returns the sequence 1, 2 :)
 
fn:data([1 to 2])        (: returns the sequence 1, 2 :)
 
[ 'a', 'b', 'c' ] = 'b'  (: returns true :)
 
[ 'a', 'b', 'c' ] = 'b'  (: returns true :)
 
<a>{ [ 1, 2 ] }</a>      (: returns <a>1 2</a> :)
 
<a>{ [ 1, 2 ] }</a>      (: returns <a>1 2</a> :)
 
array { 1 to 2 } + 3    (: error: the left operand returns two items :)
 
array { 1 to 2 } + 3    (: error: the left operand returns two items :)
</pre>
+
</syntaxhighlight>
  
 
Atomization also applies to function arguments. The following query returns 5, because the array will be atomized to a sequence of 5 integers:
 
Atomization also applies to function arguments. The following query returns 5, because the array will be atomized to a sequence of 5 integers:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
let $f := function($x as xs:integer*) { count($x) }
 
let $f := function($x as xs:integer*) { count($x) }
 
return $f([1 to 5])
 
return $f([1 to 5])
</pre>
+
</syntaxhighlight>
  
 
However, the next query returns 1, because the array is already of the general type {{Code|item()}}, and no atomization will take place:
 
However, the next query returns 1, because the array is already of the general type {{Code|item()}}, and no atomization will take place:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
let $f := function($x as item()*) { count($x) }
 
let $f := function($x as item()*) { count($x) }
 
return $f([1 to 5])
 
return $f([1 to 5])
</pre>
+
</syntaxhighlight>
  
 
Arrays can be compared with the {{Code|fn:deep-equal}} function. The [[Array Module]] describes the available set of array functions.
 
Arrays can be compared with the {{Code|fn:deep-equal}} function. The [[Array Module]] describes the available set of array functions.
Line 107: Line 105:
 
The following example demonstrates the four alternatives:
 
The following example demonstrates the four alternatives:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
let $map := map { 'R': 'red', 'G': 'green', 'B': 'blue' }
 
let $map := map { 'R': 'red', 'G': 'green', 'B': 'blue' }
 
return (
 
return (
Line 121: Line 120:
 
   $array?(2 to 3)  (: 3. returns the second and third values; same as: (1 to 2) ! $array(.) :)
 
   $array?(2 to 3)  (: 3. returns the second and third values; same as: (1 to 2) ! $array(.) :)
 
)
 
)
</pre>
+
</syntaxhighlight>
  
 
The lookup operator can also be used without left operand. In this case, the context item will be used as input. This query returns {{Code|Akureyri}}:
 
The lookup operator can also be used without left operand. In this case, the context item will be used as input. This query returns {{Code|Akureyri}}:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
let $maps := (
 
let $maps := (
 
   map { 'name': 'Guðrún', 'city': 'Reykjavík' },
 
   map { 'name': 'Guðrún', 'city': 'Reykjavík' },
Line 131: Line 131:
 
)
 
)
 
return $maps[?name = 'Hildur'] ?city
 
return $maps[?name = 'Hildur'] ?city
</pre>
+
</syntaxhighlight>
  
 
=Arrow Operator=
 
=Arrow Operator=
  
The arrow operator applies a function to a value. The value is used as the first argument to the function. It is introduced with the characters <code>=></code>, and it is followed by the function to be called. If <code>$v</code> is a value and <code>f()</code> is a function, then <code>$v=>f()</code> is equivalent to <code>f($v)</code>, and <code>$v=>f($j)</code> is equivalent to <code>f($v, $j)</code>. This is further illustrated by an example:
+
The arrow operator <code>=></code> provides a convenient alternative syntax for passing on functions to a value. The expression that precedes the operator will be supplied as first argument of the function that follows the arrow. If <code>$v</code> is a value and <code>f()</code> is a function, then <code>$v => f()</code> is equivalent to <code>f($v)</code>, and <code>$v => f($j)</code> is equivalent to <code>f($v, $j)</code>:
 +
 
 +
<syntaxhighlight lang="xquery">
  
<pre class="brush:xquery">
 
 
(: Returns 3 :)
 
(: Returns 3 :)
 
count(('A', 'B', 'C')),
 
count(('A', 'B', 'C')),
Line 154: Line 155:
 
(for $i in 'welcome' => string-to-codepoints()
 
(for $i in 'welcome' => string-to-codepoints()
 
  return $i + 1) => codepoints-to-string()
 
  return $i + 1) => codepoints-to-string()
</pre>
+
</syntaxhighlight>
  
 
The syntax makes nested function calls more readable, as it is easy to see if parentheses are balanced.
 
The syntax makes nested function calls more readable, as it is easy to see if parentheses are balanced.
Line 164: Line 165:
 
The string constructors syntax uses two backticks and a square bracket for opening and closing a string:
 
The string constructors syntax uses two backticks and a square bracket for opening and closing a string:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
(: Returns "This is a 'new' & 'flexible' syntax." :)
 
(: Returns "This is a 'new' & 'flexible' syntax." :)
 
``["This is a 'new' & 'flexible' syntax."]``
 
``["This is a 'new' & 'flexible' syntax."]``
</pre>
+
</syntaxhighlight>
  
 
XQuery expressions can be embedded via backticks and a curly bracket. The evaluated results will be separated with spaces, and all strings will eventually be concatenated:
 
XQuery expressions can be embedded via backticks and a curly bracket. The evaluated results will be separated with spaces, and all strings will eventually be concatenated:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
(: Returns »Count 1 2 3, and I will be there.« :)
 
(: Returns »Count 1 2 3, and I will be there.« :)
 
let $c := 1 to 3
 
let $c := 1 to 3
return ``[»Count `{ $c }`, and I will be there.«]``</pre>
+
return ``[»Count `{ $c }`, and I will be there.«]``</syntaxhighlight>
  
 
=Serialization=
 
=Serialization=
  
Two [[Serialization]] methods have been added to the [http://www.w3.org/TR/xslt-xquery-serialization-31 Serialization spec]:
+
Two [[Serialization]] methods have been added to the [https://www.w3.org/TR/xslt-xquery-serialization-31 Serialization spec]:
  
 
==Adaptive Serialization==
 
==Adaptive Serialization==
  
In BaseX, {{Code|adaptive}} is used as the new default serialization method. It provides a textual representation for all XDM types, including maps and arrays, functions, attributes, and namespaces. All items will be separated using the value of the {{Code|item-separator}} parameter, or a newline if no value is specified:
+
The {{Code|adaptive}} serialization provides an intuitive textual representation for all XDM types, including maps and arrays, functions, attributes, and namespaces. All items will be separated by the value of the {{Code|item-separator}} parameter, which by default is a newline character. It is utilized by the functions <code>[[Profiling Module#prof:dump|prof:dump]]</code> and <code>[https://www.w3.org/TR/xpath-functions-31/#func-trace fn:trace]</code>.
  
<pre class="brush:xquery">
+
Example:
 +
 
 +
<syntaxhighlight lang="xquery">
 +
 
 +
declare option output:method 'adaptive';
 
<element id='id0'/>/@id,
 
<element id='id0'/>/@id,
 +
xs:token("abc"),
 
map { 'key': 'value' },
 
map { 'key': 'value' },
 
true#0
 
true#0
</pre>
+
</syntaxhighlight>
  
 
Result:
 
Result:
  
<pre class="brush:xml">
+
<syntaxhighlight lang="xml">
id="id0"
+
id="id0"
{
+
xs:token("abc"),
 +
map {
 
   "key": "value"
 
   "key": "value"
 
}
 
}
function true#0
+
fn:true#0
</pre>
+
</syntaxhighlight>
  
 
==JSON Serialization==
 
==JSON Serialization==
Line 204: Line 213:
 
The new {{Code|json}} serialization output method can be used to serialize XQuery maps, arrays, atomic values and empty sequences as JSON.
 
The new {{Code|json}} serialization output method can be used to serialize XQuery maps, arrays, atomic values and empty sequences as JSON.
  
The {{Code|json}} output method has been introduced in BaseX quite a while ago. The implementation of this method now complies with the standard serialization rules and, at the same time, preserves the existing semantics:
+
The {{Code|json}} output method has been introduced in BaseX before it was added to the official specification. It complies with the standard serialization rules and, at the same time, preserves the existing semantics:
  
 
* If an XML node of type {{Code|element(json)}} is found, it will be serialized following the serialization rules of the [[JSON Module]].
 
* If an XML node of type {{Code|element(json)}} is found, it will be serialized following the serialization rules of the [[JSON Module]].
* Any other node or atomic value, map, array, or empty sequence will be serialized according to the [http://www.w3.org/TR/xslt-xquery-serialization-31/#json-output rules in the specification].
+
* Any other node or atomic value, map, array, or empty sequence will be serialized according to the [https://www.w3.org/TR/xslt-xquery-serialization-31/#json-output rules in the specification].
  
 
The following two queries will both return the JSON snippet <code>{ "key": "value" }</code>:
 
The following two queries will both return the JSON snippet <code>{ "key": "value" }</code>:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
declare option output:method 'json';
 
declare option output:method 'json';
 
map { "key": "value" }
 
map { "key": "value" }
</pre>
+
</syntaxhighlight>
 +
 
 +
<syntaxhighlight lang="xquery">
  
<pre class="brush:xquery">
 
 
declare option output:method 'json';
 
declare option output:method 'json';
 
<json type='object'>
 
<json type='object'>
 
   <key>value</key>
 
   <key>value</key>
 
</json>
 
</json>
</pre>
+
</syntaxhighlight>
  
 
=Functions=
 
=Functions=
  
The following functions of the [http://www.w3.org/TR/xpath-functions-31/ XQuery 3.1 Functions and Operators] Working Draft have been added. Please be aware that the functions are still subject to change:
+
The following functions have been added in the [https://www.w3.org/TR/xpath-functions-31/ XQuery 3.1 Functions and Operators] Specification:
  
 
==Map Functions==
 
==Map Functions==
 
The following map functions are now available:
 
  
 
<code>map:merge</code>, <code>map:size</code>, <code>map:keys</code>, <code>map:contains</code>, <code>map:get</code>, <code>map:entry</code>, <code>map:put</code>, <code>map:remove</code>, <code>map:for-each</code>
 
<code>map:merge</code>, <code>map:size</code>, <code>map:keys</code>, <code>map:contains</code>, <code>map:get</code>, <code>map:entry</code>, <code>map:put</code>, <code>map:remove</code>, <code>map:for-each</code>
Line 236: Line 245:
  
 
==Array Functions==
 
==Array Functions==
 
The following array functions are now available:
 
  
 
<code>array:size</code>, <code>array:append</code>, <code>array:subarray</code>, <code>array:remove</code>, <code>array:insert-before</code>, <code>array:head</code>, <code>array:tail</code>, <code>array:reverse</code>, <code>array:join</code>, <code>array:flatten</code>, <code>array:for-each</code>, <code>array:filter</code>, <code>array:fold-left</code>, <code>array:fold-right</code>, <code>array:for-each-pair</code>
 
<code>array:size</code>, <code>array:append</code>, <code>array:subarray</code>, <code>array:remove</code>, <code>array:insert-before</code>, <code>array:head</code>, <code>array:tail</code>, <code>array:reverse</code>, <code>array:join</code>, <code>array:flatten</code>, <code>array:for-each</code>, <code>array:filter</code>, <code>array:fold-left</code>, <code>array:fold-right</code>, <code>array:for-each-pair</code>
 
Please check out the [[Array Module]] for more details.
 
  
 
==JSON Functions==
 
==JSON Functions==
  
XQuery now provides native support for JSON objects. Strings and resources can be parsed to XQuery items and, as [[#JSON Serialization|shown above]], serialized back to their original form.
+
With XQuery 3.1, native support for JSON objects was added. Strings and resources can be parsed to XQuery items and, as [[#JSON Serialization|shown above]], serialized back to their original form.
  
 
===fn:parse-json===
 
===fn:parse-json===
Line 253: Line 258:
 
* <code>fn:parse-json($input as xs:string, $options as map(*)) as item()?</code>
 
* <code>fn:parse-json($input as xs:string, $options as map(*)) as item()?</code>
  
Parses the supplied string as JSON text and returns its item representation. The result may be a map, an array, a string, a double, a boolean, or an empty sequence. The allowed options can be looked up in the [http://www.w3.org/TR/xpath-functions-31/#func-parse-json specification].
+
Parses the supplied string as JSON text and returns its item representation. The result may be a map, an array, a string, a double, a boolean, or an empty sequence. The allowed options can be looked up in the [https://www.w3.org/TR/xpath-functions-31/#func-parse-json specification].
 +
 
 +
<syntaxhighlight lang="xquery">
  
<pre class="brush:xquery">
 
 
parse-json('{ "name": "john" }')  (: yields { "name": "json" } :),
 
parse-json('{ "name": "john" }')  (: yields { "name": "json" } :),
 
parse-json('[ 1, 2, 4, 8, 16]')    (: yields [ 1, 2, 4, 8, 16 ] :)
 
parse-json('[ 1, 2, 4, 8, 16]')    (: yields [ 1, 2, 4, 8, 16 ] :)
</pre>
+
</syntaxhighlight>
  
 
===fn:json-doc===
 
===fn:json-doc===
Line 268: Line 274:
 
Retrieves the text from the specified URI, parses the supplied string as JSON text and returns its item representation (see [[#fn:parse-json|fn:parse-json]] for more details).
 
Retrieves the text from the specified URI, parses the supplied string as JSON text and returns its item representation (see [[#fn:parse-json|fn:parse-json]] for more details).
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
json-doc("http://ip.jsontest.com/")('ip')  (: returns your IP address :)
 
json-doc("http://ip.jsontest.com/")('ip')  (: returns your IP address :)
</pre>
+
</syntaxhighlight>
  
 
===fn:json-to-xml===
 
===fn:json-to-xml===
Line 277: Line 284:
 
* <code>fn:json-to-xml($string as xs:string?) as node()?</code>
 
* <code>fn:json-to-xml($string as xs:string?) as node()?</code>
  
Converts a JSON string to an XML node representation. The allowed options can be looked up in the [http://www.w3.org/TR/xslt-30/#func-json-to-xml specification].
+
Converts a JSON string to an XML node representation. The allowed options can be looked up in the [https://www.w3.org/TR/xpath-functions-31/#func-json-to-xm specification].
 +
 
 +
<syntaxhighlight lang="xquery">
  
<pre class="brush:xquery">
 
 
json-to-xml('{ "message": "world" }')
 
json-to-xml('{ "message": "world" }')
  
Line 286: Line 294:
 
   <string key="message">world</string>
 
   <string key="message">world</string>
 
</map> :)
 
</map> :)
</pre>
+
</syntaxhighlight>
  
 
===fn:xml-to-json===
 
===fn:xml-to-json===
Line 293: Line 301:
 
* <code>fn:xml-to-json($node as node()?) as xs:string?</code>
 
* <code>fn:xml-to-json($node as node()?) as xs:string?</code>
  
Converts an XML node, whose format conforms to the results created by [[#fn:json-to-xml|fn:json-to-xml]], to a JSON string representation. The allowed options can be looked up in the [http://www.w3.org/TR/xslt-30/#func-xml-to-json specification].
+
Converts an XML node, whose format conforms to the results created by [[#fn:json-to-xml|fn:json-to-xml]], to a JSON string representation. The allowed options can be looked up in the [https://www.w3.org/TR/xpath-functions-31/#func-xml-to-json specification].
 +
 
 +
<syntaxhighlight lang="xquery">
  
<pre class="brush:xquery">
 
 
(: returns "JSON" :)
 
(: returns "JSON" :)
 
xml-to-json(<string xmlns="http://www.w3.org/2005/xpath-functions">JSON</string>)
 
xml-to-json(<string xmlns="http://www.w3.org/2005/xpath-functions">JSON</string>)
</pre>
+
</syntaxhighlight>
  
 
==fn:sort==
 
==fn:sort==
Line 304: Line 313:
 
; Signatures
 
; Signatures
 
* <code>fn:sort($input as item()*) as item()*</code>
 
* <code>fn:sort($input as item()*) as item()*</code>
* <code>fn:sort($input as item()*, $key as function(item()*) as xs:anyAtomicType*)) as item()*</code>
+
* <code>fn:sort($input as item()*, $collation as xs:string?) as xs:anyAtomicType*)) as item()*</code>
 +
* <code>fn:sort($input as item()*, $collation as xs:string?, $key as function(item()*) as xs:anyAtomicType*)) as item()*</code>
  
Returns a new sequence with sorted {{Code|$input}} items. If a sort {{Code|$key}} function is given, it will be applied on all items. The items of the resulting values will be sorted using the semantics of the {{Code|lt}} expression.
+
Returns a new sequence with sorted {{Code|$input}} items, using an optional {{Code|$collation}}. If a {{Code|$key}} function is supplied, it will be applied on all items. The items of the resulting values will be sorted using the semantics of the {{Code|lt}} expression.
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
sort(reverse(1 to 3))               (: yields 1, 2, 3 :),
+
 
sort((3, -2, 1), abs#1)             (: yields 1, -2, 3 :),
+
sort(reverse(1 to 3))                   (: yields 1, 2, 3 :),
sort((1,2,3), function($x) { -$x })  (: yields 3, 2, 1 :),
+
reverse(sort(1 to 3))                    (: returns the sorted order in descending order :),
sort((1, 'a'))                       (: yields an error, as strings and integers cannot be compared :)
+
sort((3,-2,1), (), abs#1)               (: yields 1, -2, 3 :),
</pre>
+
sort((1,2,3), (), function($x) { -$x })  (: yields 3, 2, 1 :),
 +
sort((1,'a'))                           (: yields an error, as strings and integers cannot be compared :)
 +
</syntaxhighlight>
  
 
==fn:contains-token==
 
==fn:contains-token==
Line 323: Line 335:
 
The supplied strings will be tokenized at whitespace boundaries. The function returns {{Code|true}} if one of the strings equals the supplied token, possibly under the rules of a supplied collation:
 
The supplied strings will be tokenized at whitespace boundaries. The function returns {{Code|true}} if one of the strings equals the supplied token, possibly under the rules of a supplied collation:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
contains-token(('a', 'b c', 'd'), 'c')                (: yields true :)
 
contains-token(('a', 'b c', 'd'), 'c')                (: yields true :)
 
<xml class='one two'/>/contains-token(@class, 'one')  (: yields true :)
 
<xml class='one two'/>/contains-token(@class, 'one')  (: yields true :)
</pre>
+
</syntaxhighlight>
  
 
==fn:parse-ietf-date==
 
==fn:parse-ietf-date==
Line 335: Line 348:
 
Parses a string in the IETF format (which is widely used on the Internet) and returns a {{Code|xs:dateTime}} item:
 
Parses a string in the IETF format (which is widely used on the Internet) and returns a {{Code|xs:dateTime}} item:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
fn:parse-ietf-date('28-Feb-1984 07:07:07')"              (: yields 1984-02-28T07:07:07Z :),
 
fn:parse-ietf-date('28-Feb-1984 07:07:07')"              (: yields 1984-02-28T07:07:07Z :),
 
fn:parse-ietf-date('Wed, 01 Jun 2001 23:45:54 +02:00')"  (: yields 2001-06-01T23:45:54+02:00 :)
 
fn:parse-ietf-date('Wed, 01 Jun 2001 23:45:54 +02:00')"  (: yields 2001-06-01T23:45:54+02:00 :)
</pre>
+
</syntaxhighlight>
  
 
==fn:apply==
 
==fn:apply==
  
 
; Signatures
 
; Signatures
* <code>fn:apply($function as function(*), $array as array(*)) as item()*</code>
+
* <code>fn:apply($function as function(*), $arguments as array(*)) as item()*</code>
  
A supplied function is invoked with the arguments supplied by an array. The arity of the function must be the same as the size of the array.
+
The supplied {{Code|$function}} is invoked with the specified {{Code|$arguments}}. The arity of the function must be the same as the size of the array.
  
 
Example:
 
Example:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
fn:apply(concat#5, array { 1 to 5 })            (: 12345 :)
 
fn:apply(concat#5, array { 1 to 5 })            (: 12345 :)
 
fn:apply(function($a) { sum($a) }, [ 1 to 5 ])  (: 15 :)
 
fn:apply(function($a) { sum($a) }, [ 1 to 5 ])  (: 15 :)
fn:apply(count#1, [ 1,2 ]) (: error (the array has two members) :)
+
fn:apply(count#1, [ 1,2 ])                     (: error. the array has two members :)
</pre>
+
</syntaxhighlight>
  
 
==fn:random-number-generator==
 
==fn:random-number-generator==
Line 371: Line 386:
 
Example:
 
Example:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
let $rng := fn:random-number-generator()
 
let $rng := fn:random-number-generator()
 
let $number := $rng('number')              (: returns a random number :)
 
let $number := $rng('number')              (: returns a random number :)
Line 378: Line 394:
 
let $permutation := $rng('permute')(1 to 5) (: returns a random permutation of (1,2,3,4,5) :)
 
let $permutation := $rng('permute')(1 to 5) (: returns a random permutation of (1,2,3,4,5) :)
 
return ($number, $next-number, $permutation)
 
return ($number, $next-number, $permutation)
</pre>
+
</syntaxhighlight>
  
 
==fn:format-number==
 
==fn:format-number==
Line 384: Line 400:
 
The function has been extended to support scientific notation:
 
The function has been extended to support scientific notation:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
format-number(1984.42, '00.0e0')  (: yields 19.8e2 :)
 
format-number(1984.42, '00.0e0')  (: yields 19.8e2 :)
</pre>
+
</syntaxhighlight>
  
 
==fn:tokenize==
 
==fn:tokenize==
Line 392: Line 409:
 
If no separator is specified as second argument, a string will be tokenized at whitespace boundaries:
 
If no separator is specified as second argument, a string will be tokenized at whitespace boundaries:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
fn:tokenize("  a b  c d")  (: yields "a", "b", "c", "d" :)
 
fn:tokenize("  a b  c d")  (: yields "a", "b", "c", "d" :)
</pre>
+
</syntaxhighlight>
  
 
==fn:trace==
 
==fn:trace==
Line 400: Line 418:
 
The second argument can now be omitted:
 
The second argument can now be omitted:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
fn:trace(<xml/>, "Node: ")/node()  (: yields the debugging output "Node: <xml/>" :),
 
fn:trace(<xml/>, "Node: ")/node()  (: yields the debugging output "Node: <xml/>" :),
 
fn:trace(<xml/>)/node()            (: returns the debugging output "<xml/>" :)
 
fn:trace(<xml/>)/node()            (: returns the debugging output "<xml/>" :)
</pre>
+
</syntaxhighlight>
  
 
==fn:string-join==
 
==fn:string-join==
Line 409: Line 428:
 
The type of the first argument is now <code>xs:anyAtomicType*</code>, and all items will be implicitly cast to strings:
 
The type of the first argument is now <code>xs:anyAtomicType*</code>, and all items will be implicitly cast to strings:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
fn:string-join(1 to 3)  (: yields the string "123" :)
 
fn:string-join(1 to 3)  (: yields the string "123" :)
</pre>
+
</syntaxhighlight>
  
 
==fn:default-language==
 
==fn:default-language==
  
{{Mark|Introduced with BaseX 8.4:}}
+
Returns the default language used for formatting numbers and dates. BaseX always returns {{Code|en}}.
 +
 
 +
==Appendix==
  
Returns the default language used for formatting numbers and dates. BaseX always returns {{Code|en}}.
+
The three functions <code>fn:transform</code>, <code>fn:load-xquery-module</code> and <code>fn:collation-key</code> may be added in a future version of BaseX as their implementation might require the use of additional external libraries.
  
 
=Binary Data=
 
=Binary Data=
  
Items of type <code>xs:hexBinary</code> and <code>xs:base64Binary</code> can now be compared against each other. The following queries all yield {{Code|true}}:
+
Items of type <code>xs:hexBinary</code> and <code>xs:base64Binary</code> can be compared against each other. The following queries all yield {{Code|true}}:
 +
 
 +
<syntaxhighlight lang="xquery">
  
<pre class="brush:xquery">
 
 
xs:hexBinary('') < xs:hexBinary('bb'),
 
xs:hexBinary('') < xs:hexBinary('bb'),
 
xs:hexBinary('aa') < xs:hexBinary('bb'),
 
xs:hexBinary('aa') < xs:hexBinary('bb'),
 
max((xs:hexBinary('aa'), xs:hexBinary('bb'))) = xs:hexBinary('bb')
 
max((xs:hexBinary('aa'), xs:hexBinary('bb'))) = xs:hexBinary('bb')
</pre>
+
</syntaxhighlight>
  
 
=Collations=
 
=Collations=
  
XQuery 3.1 provides a new default collation, which allows for a case-insensitive comparison of ASCII characters (<code>A-Z</code> = <code>a-z</code>). This query returns <code>true</code>:
+
XQuery 3.1 provides a default collation, which allows for a case-insensitive comparison of ASCII characters (<code>A-Z</code> = <code>a-z</code>). This query returns <code>true</code>:
 +
 
 +
<syntaxhighlight lang="xquery">
  
<pre class="brush:xquery">
 
 
declare default collation 'http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive';
 
declare default collation 'http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive';
 
'HTML' = 'html'
 
'HTML' = 'html'
</pre>
+
</syntaxhighlight>
  
If the [http://site.icu-project.org/download ICU Library] is downloaded and added to the classpath, the full [http://www.w3.org/TR/xpath-functions-31/#uca-collations Unicode Collation Algorithm] features get available in BaseX:
+
If the [http://site.icu-project.org/download ICU Library] is downloaded and added to the classpath, the full [https://www.w3.org/TR/xpath-functions-31/#uca-collations Unicode Collation Algorithm] features become available in BaseX:
 +
 
 +
<syntaxhighlight lang="xquery">
  
<pre class="brush:xquery">
 
 
(: returns 0 (both strings are compared as equal) :)
 
(: returns 0 (both strings are compared as equal) :)
 
compare('a-b', 'ab', 'http://www.w3.org/2013/collation/UCA?alternate=shifted')
 
compare('a-b', 'ab', 'http://www.w3.org/2013/collation/UCA?alternate=shifted')
</pre>
+
</syntaxhighlight>
  
 
=Enclosed Expressions=
 
=Enclosed Expressions=
  
''Enclosed expression'' is the syntactical term for the expressions that are specified inside a function body, try/catch clauses, node constructors and some other expressions. In the following example expressions, it’s the empty sequence:
+
''Enclosed expression'' is the syntactical term for the expressions that are specified inside a function body, try/catch clauses, node constructors and some other expressions. In the following example expressions, its the empty sequence:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
declare function local:x() { () };
+
 
 +
declare function local:x() { () }; i
 
try { () } catch * { () },
 
try { () } catch * { () },
 
element x { () },
 
element x { () },
 
text { () }
 
text { () }
</pre>
+
</syntaxhighlight>
  
 
With XQuery 3.1, the expression can be omitted. The following query is equivalent to the upper one:
 
With XQuery 3.1, the expression can be omitted. The following query is equivalent to the upper one:
  
<pre class="brush:xquery">
+
<syntaxhighlight lang="xquery">
 +
 
 
declare function local:x() { };
 
declare function local:x() { };
 
try { } catch * { },
 
try { } catch * { },
 
element x { }
 
element x { }
 
text { }
 
text { }
</pre>
+
</syntaxhighlight>
  
=Pending Features=
+
=Changelog=
  
The following functions have not been implemented yet:
+
;Version 8.6
  
* <code>fn:collation-key</code>, <code>fn:load-xquery-module</code>, <code>fn:transform</code>
+
* Updated: Collation argument was inserted between first and second argument.
 
 
=Changelog=
 
  
 
;Version 8.4
 
;Version 8.4
  
 
* Added: [[#String Constructors|String Constructors]], [[#fn:default-language|fn:default-language]], [[#Enclosed Expressions|Enclosed Expressions]]
 
* Added: [[#String Constructors|String Constructors]], [[#fn:default-language|fn:default-language]], [[#Enclosed Expressions|Enclosed Expressions]]
* Updated: [[#fn:string-join|fn:string-join]]
+
* Updated: [[#Adaptive Serialization|Adaptive Serialization]], [[#fn:string-join|fn:string-join]]
  
 
;Version 8.2
 
;Version 8.2
Line 484: Line 509:
 
;Version 8.1
 
;Version 8.1
  
* Updated: arrays are now based on an efficient [http://en.wikipedia.org/wiki/Finger_tree Finger Tree] implementation.
+
* Updated: arrays are now based on a [https://en.wikipedia.org/wiki/Finger_tree Finger Tree] implementation.
  
 
Introduced with Version 8.0.
 
Introduced with Version 8.0.
 
[[Category:XQuery]]
 

Revision as of 11:56, 2 July 2020

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

Maps

A map is a function that associates a set of keys with values, resulting in a collection of key/value pairs. Each key/value pair in a map is called an entry. A key is an arbitrary atomic value, and the associated value is an arbitrary sequence. Within a map, no two entries have the same key, when compared using the eq operator. It is not necessary that all the keys should be mutually comparable (for example, they can include a mixture of integers and strings).

Maps can be constructed as follows:

<syntaxhighlight lang="xquery"> map { }, (: empty map :) map { 'key': true(), 1984: (<a/>, ) }, (: map with two entries :) map:merge( (: map with ten entries :)

 for $i in 1 to 10
 return map { $i: 'value' || $i }

) </syntaxhighlight>

The function corresponding to the map has the signature function($key as xs:anyAtomicType) as item()*. The expression $map($key) returns the associated value; the function call map:get($map, $key) is equivalent. For example, if $books-by-isbn is a map whose keys are ISBNs and whose associated values are book elements, then the expression $books-by-isbn("0470192747") returns the book element with the given ISBN. The fact that a map is a function item allows it to be passed as an argument to Higher-Order Functions that expect a function item as one of their arguments. As an example, the following query uses the higher-order function fn:map($f, $seq) to extract all bound values from a map:

<syntaxhighlight lang="xquery"> let $map := map { 'foo': 42, 'bar': 'baz', 123: 456 } return fn:for-each(map:keys($map), $map) </syntaxhighlight>

This returns some permutation of (42, 'baz', 456).

Because a map is a function item, functions that apply to functions also apply to maps. A map is an anonymous function, so fn:function-name returns the empty sequence; fn:function-arity always returns 1.

Like all other values, maps are immutable. For example, the map:remove function creates a new map by removing an entry from an existing map, but the existing map is not changed by the operation. Like sequences, maps have no identity. It is meaningful to compare the contents of two maps, but there is no way of asking whether they are "the same map": two maps with the same content are indistinguishable.

Maps may be compared using the fn:deep-equal function. The Map Module describes the available set of map functions.

Arrays

An array is a function that associates a set of positions, represented as positive integer keys, with values. The first position in an array is associated with the integer 1. The values of an array are called its members. In the type hierarchy, array has a distinct type, which is derived from function. In BaseX, arrays (as well as sequences) are based on an efficient Finger Tree implementation.

Arrays can be constructed in two ways. With the square bracket notation, the comma serves as delimiter:

<syntaxhighlight lang="xquery">

[], (: empty array :) [ (1, 2) ], (: array with single member :) [ 1 to 2, 3 ] (: array with two members; same as: [ (1, 2), 3 ] :) </syntaxhighlight>

With the array keyword and curly brackets, the inner expression is evaluated as usual, and the resulting values will be the members of the array:

<syntaxhighlight lang="xquery">

array { }, (: empty array; same as: array { () } :) array { (1, 2) }, (: array with two members; same as: array { 1, 2 } :) array { 1 to 2, 3 } (: array with three members; same as: array { 1, 2, 3 } :) </syntaxhighlight>

The function corresponding to the array has the signature function($index as xs:integer) as item()*. The expression $array($index) returns an addressed member of the array. The following query returns the five array members 48 49 50 51 52 as result:

<syntaxhighlight lang="xquery">

let $array := array { 48 to 52 } for $i in 1 to array:size($array) return $array($i) </syntaxhighlight>

Like all other values, arrays are immutable. For example, the array:reverse function creates a new array containing a re-ordering of the members of an existing array, but the existing array is not changed by the operation. Like sequences, arrays have no identity. It is meaningful to compare the contents of two arrays, but there is no way of asking whether they are "the same array": two arrays with the same content are indistinguishable.

Atomization

If an array is atomized, all of its members will be atomized. As a result, an atomized item may now result in more than one item. Some examples:

<syntaxhighlight lang="xquery">

fn:data([1 to 2]) (: returns the sequence 1, 2 :) [ 'a', 'b', 'c' ] = 'b' (: returns true :) <a>{ [ 1, 2 ] }</a> (: returns <a>1 2</a> :) array { 1 to 2 } + 3 (: error: the left operand returns two items :) </syntaxhighlight>

Atomization also applies to function arguments. The following query returns 5, because the array will be atomized to a sequence of 5 integers:

<syntaxhighlight lang="xquery">

let $f := function($x as xs:integer*) { count($x) } return $f([1 to 5]) </syntaxhighlight>

However, the next query returns 1, because the array is already of the general type item(), and no atomization will take place:

<syntaxhighlight lang="xquery">

let $f := function($x as item()*) { count($x) } return $f([1 to 5]) </syntaxhighlight>

Arrays can be compared with the fn:deep-equal function. The Array Module describes the available set of array functions.

Lookup Operator

The lookup operator provides some syntactic sugar to access values of maps or array members. It is introduced by the question mark (?) and followed by a specifier. The specifier can be:

  1. A wildcard *,
  2. The name of the key,
  3. The integer offset, or
  4. Any other parenthesized expression.

The following example demonstrates the four alternatives:

<syntaxhighlight lang="xquery">

let $map := map { 'R': 'red', 'G': 'green', 'B': 'blue' } return (

 $map?*          (: 1. returns all values; same as: map:keys($map) ! $map(.) :),
 $map?R          (: 2. returns the value associated with the key 'R'; same as: $map('R') :),
 $map?('G','B')  (: 3. returns the values associated with the key 'G' and 'B' :)

),

let $array := [ 'one', 'two', 'three' ] return (

 $array?*         (: 1. returns all values; same as: (1 to array:size($array)) ! $array(.) :),
 $array?1         (: 2. returns the first value; same as: $array(1) :),
 $array?(2 to 3)  (: 3. returns the second and third values; same as: (1 to 2) ! $array(.) :)

) </syntaxhighlight>

The lookup operator can also be used without left operand. In this case, the context item will be used as input. This query returns Akureyri:

<syntaxhighlight lang="xquery">

let $maps := (

 map { 'name': 'Guðrún', 'city': 'Reykjavík' },
 map { 'name': 'Hildur', 'city': 'Akureyri' }

) return $maps[?name = 'Hildur'] ?city </syntaxhighlight>

Arrow Operator

The arrow operator => provides a convenient alternative syntax for passing on functions to a value. The expression that precedes the operator will be supplied as first argument of the function that follows the arrow. If $v is a value and f() is a function, then $v => f() is equivalent to f($v), and $v => f($j) is equivalent to f($v, $j):

<syntaxhighlight lang="xquery">

(: Returns 3 :) count(('A', 'B', 'C')), ('A', 'B', 'C') => count(), ('A', 'B', 'C') => (function( $sequence) { count( $sequence)})(),

(: Returns W-E-L-C-O-M-E :) string-join(tokenize(upper-case('w e l c o m e')), '-'), 'w e l c o m e' => upper-case() => tokenize() => string-join('-'),

(: Returns xfmdpnf :) codepoints-to-string(

 for $i in string-to-codepoints('welcome')
 return $i + 1

), (for $i in 'welcome' => string-to-codepoints()

return $i + 1) => codepoints-to-string()

</syntaxhighlight>

The syntax makes nested function calls more readable, as it is easy to see if parentheses are balanced.

String Constructor

The string constructor has been inspired by here document literals of the Unix shell and script languages. It allows you to generate strings that contain various characters that would otherwise be interpreted as XQuery delimiters.

The string constructors syntax uses two backticks and a square bracket for opening and closing a string:

<syntaxhighlight lang="xquery">

(: Returns "This is a 'new' & 'flexible' syntax." :) ``["This is a 'new' & 'flexible' syntax."]`` </syntaxhighlight>

XQuery expressions can be embedded via backticks and a curly bracket. The evaluated results will be separated with spaces, and all strings will eventually be concatenated:

<syntaxhighlight lang="xquery">

(: Returns »Count 1 2 3, and I will be there.« :) let $c := 1 to 3 return ``[»Count `{ $c }`, and I will be there.«]``</syntaxhighlight>

Serialization

Two Serialization methods have been added to the Serialization spec:

Adaptive Serialization

The adaptive serialization provides an intuitive textual representation for all XDM types, including maps and arrays, functions, attributes, and namespaces. All items will be separated by the value of the item-separator parameter, which by default is a newline character. It is utilized by the functions prof:dump and fn:trace.

Example:

<syntaxhighlight lang="xquery">

declare option output:method 'adaptive'; <element id='id0'/>/@id, xs:token("abc"), map { 'key': 'value' }, true#0 </syntaxhighlight>

Result:

<syntaxhighlight lang="xml"> id="id0" xs:token("abc"), map {

 "key": "value"

} fn:true#0 </syntaxhighlight>

JSON Serialization

The new json serialization output method can be used to serialize XQuery maps, arrays, atomic values and empty sequences as JSON.

The json output method has been introduced in BaseX before it was added to the official specification. It complies with the standard serialization rules and, at the same time, preserves the existing semantics:

  • If an XML node of type element(json) is found, it will be serialized following the serialization rules of the JSON Module.
  • Any other node or atomic value, map, array, or empty sequence will be serialized according to the rules in the specification.

The following two queries will both return the JSON snippet { "key": "value" }:

<syntaxhighlight lang="xquery">

declare option output:method 'json'; map { "key": "value" } </syntaxhighlight>

<syntaxhighlight lang="xquery">

declare option output:method 'json'; <json type='object'>

 <key>value</key>

</json> </syntaxhighlight>

Functions

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

Map Functions

map:merge, map:size, map:keys, map:contains, map:get, map:entry, map:put, map:remove, map:for-each

Please check out the Map Module for more details.

Array Functions

array:size, array:append, array:subarray, array:remove, array:insert-before, array:head, array:tail, array:reverse, array:join, array:flatten, array:for-each, array:filter, array:fold-left, array:fold-right, array:for-each-pair

JSON Functions

With XQuery 3.1, native support for JSON objects was added. Strings and resources can be parsed to XQuery items and, as shown above, serialized back to their original form.

fn:parse-json

Signatures
  • fn:parse-json($input as xs:string) as item()?
  • fn:parse-json($input as xs:string, $options as map(*)) as item()?

Parses the supplied string as JSON text and returns its item representation. The result may be a map, an array, a string, a double, a boolean, or an empty sequence. The allowed options can be looked up in the specification.

<syntaxhighlight lang="xquery">

parse-json('{ "name": "john" }') (: yields { "name": "json" } :), parse-json('[ 1, 2, 4, 8, 16]') (: yields [ 1, 2, 4, 8, 16 ] :) </syntaxhighlight>

fn:json-doc

Signatures
  • fn:json-doc($uri as xs:string) as item()?
  • fn:json-doc($uri as xs:string, $options as map(*)) as item()?

Retrieves the text from the specified URI, parses the supplied string as JSON text and returns its item representation (see fn:parse-json for more details).

<syntaxhighlight lang="xquery">

json-doc("http://ip.jsontest.com/")('ip') (: returns your IP address :) </syntaxhighlight>

fn:json-to-xml

Signatures
  • fn:json-to-xml($string as xs:string?) as node()?

Converts a JSON string to an XML node representation. The allowed options can be looked up in the specification.

<syntaxhighlight lang="xquery">

json-to-xml('{ "message": "world" }')

(: result: <map xmlns="http://www.w3.org/2005/xpath-functions">

 <string key="message">world</string>

</map> :) </syntaxhighlight>

fn:xml-to-json

Signatures
  • fn:xml-to-json($node as node()?) as xs:string?

Converts an XML node, whose format conforms to the results created by fn:json-to-xml, to a JSON string representation. The allowed options can be looked up in the specification.

<syntaxhighlight lang="xquery">

(: returns "JSON" :) xml-to-json(<string xmlns="http://www.w3.org/2005/xpath-functions">JSON</string>) </syntaxhighlight>

fn:sort

Signatures
  • fn:sort($input as item()*) as item()*
  • fn:sort($input as item()*, $collation as xs:string?) as xs:anyAtomicType*)) as item()*
  • fn:sort($input as item()*, $collation as xs:string?, $key as function(item()*) as xs:anyAtomicType*)) as item()*

Returns a new sequence with sorted $input items, using an optional $collation. If a $key function is supplied, it will be applied on all items. The items of the resulting values will be sorted using the semantics of the lt expression.

<syntaxhighlight lang="xquery">

sort(reverse(1 to 3)) (: yields 1, 2, 3 :), reverse(sort(1 to 3)) (: returns the sorted order in descending order :), sort((3,-2,1), (), abs#1) (: yields 1, -2, 3 :), sort((1,2,3), (), function($x) { -$x }) (: yields 3, 2, 1 :), sort((1,'a')) (: yields an error, as strings and integers cannot be compared :) </syntaxhighlight>

fn:contains-token

Signatures
  • fn:contains-token($input as xs:string*, $token as string) as xs:boolean
  • fn:contains-token($input as xs:string*, $token as string, $collation as xs:string) as xs:boolean

The supplied strings will be tokenized at whitespace boundaries. The function returns true if one of the strings equals the supplied token, possibly under the rules of a supplied collation:

<syntaxhighlight lang="xquery">

contains-token(('a', 'b c', 'd'), 'c') (: yields true :) <xml class='one two'/>/contains-token(@class, 'one') (: yields true :) </syntaxhighlight>

fn:parse-ietf-date

Signature
  • fn:parse-ietf-date($input as xs:string?) as xs:string?

Parses a string in the IETF format (which is widely used on the Internet) and returns a xs:dateTime item:

<syntaxhighlight lang="xquery">

fn:parse-ietf-date('28-Feb-1984 07:07:07')" (: yields 1984-02-28T07:07:07Z :), fn:parse-ietf-date('Wed, 01 Jun 2001 23:45:54 +02:00')" (: yields 2001-06-01T23:45:54+02:00 :) </syntaxhighlight>

fn:apply

Signatures
  • fn:apply($function as function(*), $arguments as array(*)) as item()*

The supplied $function is invoked with the specified $arguments. The arity of the function must be the same as the size of the array.

Example:

<syntaxhighlight lang="xquery">

fn:apply(concat#5, array { 1 to 5 }) (: 12345 :) fn:apply(function($a) { sum($a) }, [ 1 to 5 ]) (: 15 :) fn:apply(count#1, [ 1,2 ]) (: error. the array has two members :) </syntaxhighlight>

fn:random-number-generator

Signatures
  • fn:random-number-generator() as map(xs:string, item())
  • fn:random-number-generator($seed as xs:anyAtomicType) as map(xs:string, item())

Creates a random number generator, using an optional seed. The returned map contains three entries:

  • number is a random double between 0 and 1
  • next is a function that returns another random number generator
  • permute is a function that returns a random permutation of its argument

The returned random generator is deterministic: If the function is called twice with the same arguments and in the same execution scope, it will always return the same result.

Example:

<syntaxhighlight lang="xquery">

let $rng := fn:random-number-generator() let $number := $rng('number') (: returns a random number :) let $next-rng := $rng('next')() (: returns a new generator :) let $next-number := $next-rng('number') (: returns another random number :) let $permutation := $rng('permute')(1 to 5) (: returns a random permutation of (1,2,3,4,5) :) return ($number, $next-number, $permutation) </syntaxhighlight>

fn:format-number

The function has been extended to support scientific notation:

<syntaxhighlight lang="xquery">

format-number(1984.42, '00.0e0') (: yields 19.8e2 :) </syntaxhighlight>

fn:tokenize

If no separator is specified as second argument, a string will be tokenized at whitespace boundaries:

<syntaxhighlight lang="xquery">

fn:tokenize(" a b c d") (: yields "a", "b", "c", "d" :) </syntaxhighlight>

fn:trace

The second argument can now be omitted:

<syntaxhighlight lang="xquery">

fn:trace(<xml/>, "Node: ")/node() (: yields the debugging output "Node: <xml/>" :), fn:trace(<xml/>)/node() (: returns the debugging output "<xml/>" :) </syntaxhighlight>

fn:string-join

The type of the first argument is now xs:anyAtomicType*, and all items will be implicitly cast to strings:

<syntaxhighlight lang="xquery">

fn:string-join(1 to 3) (: yields the string "123" :) </syntaxhighlight>

fn:default-language

Returns the default language used for formatting numbers and dates. BaseX always returns en.

Appendix

The three functions fn:transform, fn:load-xquery-module and fn:collation-key may be added in a future version of BaseX as their implementation might require the use of additional external libraries.

Binary Data

Items of type xs:hexBinary and xs:base64Binary can be compared against each other. The following queries all yield true:

<syntaxhighlight lang="xquery">

xs:hexBinary() < xs:hexBinary('bb'), xs:hexBinary('aa') < xs:hexBinary('bb'), max((xs:hexBinary('aa'), xs:hexBinary('bb'))) = xs:hexBinary('bb') </syntaxhighlight>

Collations

XQuery 3.1 provides a default collation, which allows for a case-insensitive comparison of ASCII characters (A-Z = a-z). This query returns true:

<syntaxhighlight lang="xquery">

declare default collation 'http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive'; 'HTML' = 'html' </syntaxhighlight>

If the ICU Library is downloaded and added to the classpath, the full Unicode Collation Algorithm features become available in BaseX:

<syntaxhighlight lang="xquery">

(: returns 0 (both strings are compared as equal) :) compare('a-b', 'ab', 'http://www.w3.org/2013/collation/UCA?alternate=shifted') </syntaxhighlight>

Enclosed Expressions

Enclosed expression is the syntactical term for the expressions that are specified inside a function body, try/catch clauses, node constructors and some other expressions. In the following example expressions, its the empty sequence:

<syntaxhighlight lang="xquery">

declare function local:x() { () }; i try { () } catch * { () }, element x { () }, text { () } </syntaxhighlight>

With XQuery 3.1, the expression can be omitted. The following query is equivalent to the upper one:

<syntaxhighlight lang="xquery">

declare function local:x() { }; try { } catch * { }, element x { } text { } </syntaxhighlight>

Changelog

Version 8.6
  • Updated: Collation argument was inserted between first and second argument.
Version 8.4
Version 8.2
Version 8.1
  • Updated: arrays are now based on a Finger Tree implementation.

Introduced with Version 8.0.