This article is part of the [[XQuery|XQuery Portal]].It summarizes provides a summary of the new most important features of the [httphttps://www.w3.org/TR/xquery-31/ XQuery 3.1] and[http://www.w3.org/TR/xpath-functions-31/ XQuery 3.1 Functions and Operators] specificationsthat are already supported by BaseX. Please note that not all of the features that are listed on this page are alreadyfound 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 themost recently added featuresRecommendation.
=Maps=
Maps can be constructed as follows:
<pre classlang="brush:'xquery"'>
map { }, (: empty map :)
map { 'key': true(), 1984: (<a/>, <b/>) }, (: map with two entries :)
</pre>
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[[Higher-order functions 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 classlang="brush:'xquery"'>
let $map := map { 'foo': 42, 'bar': 'baz', 123: 456 }
return fn:for-each(map:keys($map), $map)
Because a map is a function item, functions that apply to functions also apply to maps. A map is an anonymous function, so {{Code|fn:function-name}} returns the empty sequence; {{Code|fn:function-arity}} always returns {{Code|1}}.
Like all other values, maps are immutable. For example, the <code>[[{{Function|Map Module#map:remove|map:remove]]</code> }} 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 {{Code|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 {{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 [httphttps://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:
<pre classlang="brush:'xquery"'>
[], (: empty array :)
[ (1, 2) ], (: array with single member :)
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 classlang="brush:'xquery"'>
array { }, (: empty array; same as: array { () } :)
array { (1, 2) }, (: array with two members; same as: array { 1, 2 } :)
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 classlang="brush:'xquery"'>
let $array := array { 48 to 52 }
for $i in 1 to array:size($array)
</pre>
Like all other values, arrays are immutable. For example, the <code>[[{{Function|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.
==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:
<pre classlang="brush:'xquery"'>
fn:data([1 to 2]) (: returns the sequence 1, 2 :)
[ 'a', 'b', 'c' ] = 'b' (: returns true :)
Atomization also applies to function arguments. The following query returns 5, because the array will be atomized to a sequence of 5 integers:
<pre classlang="brush:'xquery"'>
let $f := function($x as xs:integer*) { count($x) }
return $f([1 to 5])
However, the next query returns 1, because the array is already of the general type {{Code|item()}}, and no atomization will take place:
<pre classlang="brush:'xquery"'>
let $f := function($x as item()*) { count($x) }
return $f([1 to 5])
The following example demonstrates the four alternatives:
<pre classlang="brush:'xquery"'>
let $map := map { 'R': 'red', 'G': 'green', 'B': 'blue' }
return (
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 classlang="brush:'xquery"'>
let $maps := (
map { 'name': 'Guðrún', 'city': 'Reykjavík' },
=Arrow Operator=
The arrow operator applies <code>=></code> provides a function convenient alternative syntax for passing on functions to a value. The value is used expression that precedes the operator will be supplied as the first argument to of the function. It is introduced with the characters <code>=></code>, and it is followed by that follows the function to be calledarrow. 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:
<pre classlang="brush:'xquery"'>
(: Returns 3 :)
count(('A', 'B', 'C')),
The string constructors syntax uses two backticks and a square bracket for opening and closing a string:
<pre classlang="brush:'xquery"'>
(: Returns "This is a 'new' & 'flexible' syntax." :)
``["This is a 'new' & 'flexible' syntax."]``
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 classlang="brush:'xquery"'>
(: Returns »Count 1 2 3, and I will be there.« :)
let $c := 1 to 3
=Serialization=
Two [[Serialization]] methods have been added to the [httphttps://www.w3.org/TR/xslt-xquery-serialization-31 Serialization spec]:
==Adaptive Serialization==
In BaseX, The {{Code|adaptive}} is used as the new default serialization method. It provides a an intuitive textual representation for all XDM types, including maps and arrays, functions, attributes, and namespaces. All items will be separated using by the value of the {{Code|item-separator}} parameter, or which by default is a newline if no value character. It is specifiedutilized by the functions {{Function|Profiling|prof:dump}} and <code>[https://www.w3.org/TR/xpath-functions-31/#func-trace fn:trace]</code>. Example:
<pre classlang="brush:'xquery"'>declare option output:method 'adaptive';
<element id='id0'/>/@id,
xs:token("abc"),
map { 'key': 'value' },
true#0
Result:
<pre classlang="brush:xml"> id="id0"xs:token("abc"),map {
"key": "value"
}
function fn:true#0
</pre>
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 agobefore it was added to the official specification. The implementation of this method now 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]].
* Any other node or atomic value, map, array, or empty sequence will be serialized according to the [httphttps://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>:
<pre classlang="brush:'xquery"'>
declare option output:method 'json';
map { "key": "value" }
</pre>
<pre classlang="brush:'xquery"'>
declare option output:method 'json';
<json type='object'>
=Functions=
The following functions of have been added in the [httphttps://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 changeSpecification:
==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>
==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>
==JSON Functions==
With XQuery now provides 3.1, native support for JSON objectswas 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===
; Signatures* <codepre>fn:parse-json( $input json as xs:string) as item()?</code>* <code>fn:parse-json($input as xs:string, $options as map(*) := ()) as item()?</codepre>
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 [httphttps://www.w3.org/TR/xpath-functions-31/#func-parse-json specification].
<pre classlang="brush:'xquery"'>
parse-json('{ "name": "john" }') (: yields { "name": "json" } :),
parse-json('[ 1, 2, 4, 8, 16]') (: yields [ 1, 2, 4, 8, 16 ] :)
===fn:json-doc===
; Signatures* <codepre>fn:json-doc( $uri href as xs:string) as item()?</code>* <code>fn:json-doc($uri as xs:string, $options as map(*) := ()) as item()?</codepre>
Retrieves the text from the specified URI, parses the supplied string as JSON text and returns its item representation (see [[#fn:parse-json{{Function||fn:parse-json]] }} for more details).
<pre classlang="brush:'xquery"'>
json-doc("http://ip.jsontest.com/")('ip') (: returns your IP address :)
</pre>
===fn:json-to-xml===
; Signatures* <codepre>fn:json-to-xml( $string json as xs:string? $options as map(*) := ()) as document-node()?</codepre>
Converts a JSON string to an XML node representation. The allowed options can be looked up in the [httphttps://www.w3.org/TR/xsltxpath-30functions-31/#func-json-to-xml xm specification].
<pre classlang="brush:'xquery"'>
json-to-xml('{ "message": "world" }')
===fn:xml-to-json===
; Signatures* <codepre>fn:xml-to-json( $node as nodexs:string? $options as map(*) := ()?) as xs:string?</codepre>
Converts an XML node, whose format conforms to the results created by [[#fn:json-to-xml{{Function||fn:json-to-xml]]}}, to a JSON string representation. The allowed options can be looked up in the [httphttps://www.w3.org/TR/xsltxpath-functions-3031/#func-xml-to-json specification].
<pre classlang="brush:'xquery"'>
(: returns "JSON" :)
xml-to-json(<string xmlns="http://www.w3.org/2005/xpath-functions">JSON</string>)
==fn:sort==
; Signatures* <codepre>fn:sort( $input as item()*) , $collation as item()*</code>* <code>xs:string? := fn:sort($input as itemdefault-collation()*, $key as function(item()*) as xs:anyAtomicType*) := fn:data#1) as item()*</codepre>
Returns a new sequence with sorted {{Code|$input}} items, using an optional {{Code|$collation}}. If a sort {{Code|$key}} function is givensupplied, 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 classlang="brush:'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 :)
</pre>
==fn:contains-token==
; Signatures* <codepre>fn:contains-token( $input value as xs:string*, $token as string) as xs:boolean</code>* <code>fn:contains-token($input as xs:string*, $token as string, $collation as xs:string? := fn:default-collation()) as xs:boolean</codepre>
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 classlang="brush:'xquery"'>
contains-token(('a', 'b c', 'd'), 'c') (: yields true :)
<xml class='one two'/>/contains-token(@class, 'one') (: yields true :)
==fn:parse-ietf-date==
; Signature* <codepre>fn:parse-ietf-date( $input value as xs:string?) as xs:stringdateTime?</codepre>
Parses a string in the IETF format (which is widely used on the Internet) and returns a {{Code|xs:dateTime}} item:
<pre classlang="brush:'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 :)
==fn:apply==
; Signatures* <codepre>fn:apply( $function as function(*), $array arguments as array(*)) as item()*</codepre>
A The supplied {{Code|$function }} is invoked with the specified {{Code|$arguments supplied by an array}}. The arity of the function must be the same as the size of the array.
Example:
<pre classlang="brush:'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) :)
</pre>
==fn:random-number-generator==
; Signatures* <codepre>fn:random-number-generator() as map(xs:string, item())</code>* <code>fn:random-number-generator( $seed as xs:anyAtomicType? := ()) as map(xs:string, item())</codepre>
Creates a random number generator, using an optional seed. The returned map contains three entries:
Example:
<pre classlang="brush:'xquery"'>
let $rng := fn:random-number-generator()
let $number := $rng('number') (: returns a random number :)
The function has been extended to support scientific notation:
<pre classlang="brush:'xquery"'>
format-number(1984.42, '00.0e0') (: yields 19.8e2 :)
</pre>
If no separator is specified as second argument, a string will be tokenized at whitespace boundaries:
<pre classlang="brush:'xquery"'>
fn:tokenize(" a b c d") (: yields "a", "b", "c", "d" :)
</pre>
The second argument can now be omitted:
<pre classlang="brush:'xquery"'>
fn:trace(<xml/>, "Node: ")/node() (: yields the debugging output "Node: <xml/>" :),
fn:trace(<xml/>)/node() (: returns the debugging output "<xml/>" :)
The type of the first argument is now <code>xs:anyAtomicType*</code>, and all items will be implicitly cast to strings:
<pre classlang="brush:'xquery"'>
fn:string-join(1 to 3) (: yields the string "123" :)
</pre>
==fn:default-language==
Returns the default language used for formatting numbers and dates. BaseX always returns {{MarkCode|Introduced with BaseX 8.4:en}}. ==Appendix==
Returns the default language used for formatting numbers The three functions <code>fn:transform</code>, <code>fn:load-xquery-module</code> and dates. <code>fn:collation-key</code> may be added in a future version of BaseX always returns {{Code|en}}as their implementation might require the use of additional external libraries.
=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}}:
<pre classlang="brush:'xquery"'>
xs:hexBinary('') < xs:hexBinary('bb'),
xs:hexBinary('aa') < xs:hexBinary('bb'),
=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>:
<pre classlang="brush:'xquery"'>
declare default collation 'http://www.w3.org/2005/xpath-functions/collation/html-ascii-case-insensitive';
'HTML' = 'html'
</pre>
If the [http://site.icu-project.org/download ICU Library] is downloaded and added to the classpath, the full [httphttps://www.w3.org/TR/xpath-functions-31/#uca-collations Unicode Collation Algorithm] features get become available in BaseX:
<pre classlang="brush:'xquery"'>
(: returns 0 (both strings are compared as equal) :)
compare('a-b', 'ab', 'http://www.w3.org/2013/collation/UCA?alternate=shifted')
=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 its the empty sequence:
<pre classlang="brush:'xquery"'>
declare function local:x() { () };
try { () } catch * { () },
With XQuery 3.1, the expression can be omitted. The following query is equivalent to the upper one:
<pre classlang="brush:'xquery"'>
declare function local:x() { };
try { } catch * { },
</pre>
=Pending FeaturesChangelog= The following functions have not been implemented yet:
* <code>fn:collation-key</code>, <code>fn:load-xquery-module</code>, <code>fn:transform</code>;Version 8.6
=Changelog=* Updated: Collation argument was inserted between first and second argument.
;Version 8.4
* Added: [[#String Constructors|String Constructors]], [[#fn:default-language{{Code|fn:default-language]]}}, [[#Enclosed Expressions|Enclosed Expressions]]* Updated: [[#fn:string-joinAdaptive Serialization|Adaptive Serialization]], {{Code|fn:string-join]]}}
;Version 8.2
* Added: [[#fn:json-to-xml{{Code|fn:json-to-xml]]}}, [[#fn:xml-to-json{{Code|fn:xml-to-json]]}}.
;Version 8.1
* Updated: arrays are now based on an efficient a [httphttps://en.wikipedia.org/wiki/Finger_tree Finger Tree] implementation.
Introduced with Version 8.0.
[[Category:XQuery]]