Difference between revisions of "XQuery 3.1"
Line 182: | Line 182: | ||
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> | ||
+ | |||
+ | ===fn:parse-ietf-date=== | ||
+ | |||
+ | ; Signature | ||
+ | * <code>fn:parse-ietf-date($input as xs:string?) as xs:string?</code> | ||
+ | |||
+ | 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"> | ||
+ | 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" :) | ||
</pre> | </pre> | ||
Line 219: | Line 231: | ||
* Support for JSON: <code>fn:json-doc</code>, <code>fn:parse-json</code> | * Support for JSON: <code>fn:json-doc</code>, <code>fn:parse-json</code> | ||
− | * New functions: <code>fn:collation-key</code>, <code>fn:load-module | + | * New functions: <code>fn:collation-key</code>, <code>fn:load-module</code>, <code>fn:transform</code> |
=Changelog= | =Changelog= |
Revision as of 21:21, 27 August 2014
This article is part of the XQuery Portal. It summarizes the new features of the XQuery 3.1 Working Draft that are already supported by BaseX.
Contents
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:
map { }, (: empty map :) map { 'key': true(), 1984: (<a/>, <b/>) }, (: map with two entries :) map:merge( (: map with ten entries :) for $i in 1 to 10 return map { $i: 'value' || $i } )
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:
let $map := map { 'foo': 42, 'bar': 'baz', 123: 456 } return fn:for-each(map:keys($map), $map)
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.
Arrays can be constructed in two ways. With the square bracket notation, the comma serves as delimiter:
[], (: empty array :) [ (1, 2) ], (: array with single member :) [ 1 to 2, 3 ] (: array with two members; same as: [ (1, 2), 3 ] :)
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:
array { }, (: empty array; same as: array { () } :) array { (1, 2) }, (: array with three members; same as: array { 1, 2 } :) array { 1 to 2, 3 } (: array with three members; same as: array { 1, 2, 3 } :)
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:
let $array := array { 48 to 52 } for $i in 1 to array:size($array) return $array($i)
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:
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 :)
Atomization also applies to function arguments. The following query returns 5, because the array will be atomized to a sequence of 5 integers:
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 item()
, and no atomization will take place:
let $f := function($x as item()*) { count($x) } return $f([1 to 5])
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 at a specified position. It is introduced by the question mark (?
) and followed by a specifier. The specifier can be:
- A wildcard
*
, - The name of the key,
- The integer offset, or
- Any other parenthesized expression.
The following example demonstrates the four alternatives:
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') (: 4. 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 (: 3. returns the first value; same as: $array(2) :), $array?(2 to 3) (: 4. returns the values 2 and 3 :) )
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
:
for $map in ( map { 'name': 'Guðrún', 'city': 'Reykjavík' }, map { 'name': 'Hildur', 'city': 'Akureyri' } ) return $map[?name = 'Hildur'] ?city
Arrow Operator
The arrow operator applies a function to an item. The item is used as the first argument to the function. It is introduced with the characters =>
, and it is followed by the function to be called. If $i
is an item and f()
is a function, then $i=>f()
is equivalent to f($i)
, and $i=>f($j)
is equivalent to f($i, $j)
. This is further illustrated by an example:
(: Returns 3 :) count(('A', 'B', 'C')), ('A', 'B', 'C') => count(), (: 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()
The syntax makes nested function calls more readable, as it is easy to see if parentheses are balanced.
Functions
The following functions of the XQuery 3.1 Functions and Operators Working Draft have been added. Please be aware that the functions are still subject to change:
Map Functions
The following map functions are now available:
map:merge
, map:size
, map:keys
, map:contains
, map:get
, map:entry
, map:put
, map:remove
, map:for-each-entry
Please check out the Map Module for more details.
Array Functions
The following array functions are now available:
array:size
, array:append
, array:subarray
, array:remove
, array:insert-before
, array:head
, array:tail
, array:reverse
, array:join
, array:for-each-member
, array:filter
, array:fold-left
, array:fold-right
, array:for-each-pair
Please check out the Array Module for more details.
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:
contains-token(('a', 'b c', 'd'), 'c') (: yields true :) <xml class='one two'/>/contains-token(@class, 'one') (: yields true :)
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:
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:format-number
The function has been extended to support scientific notation:
format-number(1984.42, '00.0E0') (: yields 19.8e2 :)
fn:tokenize
If no separator is specified, a string will be tokenized at whitespace boundaries:
fn:tokenize(" a b c d") (: yields "a", "b", "c", "d" :)
Binary Data
Items of type xs:hexBinary
and xs:base64Binary
can now be compared against each other. The following queries all yield true
:
xs:hexBinary('') < xs:hexBinary('bb'), xs:hexBinary('aa') < xs:hexBinary('bb'), max((xs:hexBinary('aa'), xs:hexBinary('bb'))) = xs:hexBinary('bb')
Collations
A new Case-Insensitive Collation was added, which ignores the case of ASCII characters.
Pending Features
The features of XQuery 3.1 are still subject to change, but we are planning to add the following enhancements in near future:
- Support for JSON:
fn:json-doc
,fn:parse-json
- New functions:
fn:collation-key
,fn:load-module
,fn:transform
Changelog
Introduced with Version 8.0.