FlowForceMissionKitMobileTogetherMobileTogetherMobileTogether



Chapter 7:  XPath 3.1


XPath 3.1 became a Candidate Recommendation on 18 December, 2014.


XPath 3.1 conforms to the following specifications:






The most significant addition to XPath 3.1 is support for arrays and maps.

Prior to XPath 3.1 the only supported complex data structures were sequences and element structures. Arrays were introduced to XPath 3.1 because sequences are always flat. It is impossible to construct hierarchical sequences (e.g. a sequence of sequences). Arrays do not have this limitation i.e. it is possible to construct multidimensional arrays (an array of arrays etc.) Maps store data in key/value pairs and provide an extremely quick method of searching according to the key value.

In addition to arrays and maps, XPath 3.1 also introduces support for new operators and built-in functions.



7.1    Arrays




Arrays are a collection of values associated with positions.

Each entry in an array is referred to as a 'member'.

The first member of an array has an index of 1, this simply means that it is located at position 1.

Arrays can also be nested i.e. an array can contain members which are themselves arrays.

There are two ways to construct arrays - using a square bracket constructor or using a curly bracket constructor.


Square bracket array constructor
[ 5, 10, 6, 2 ]
  • This array declaration uses a square bracket array constructor to create an array of four integer values 5, 10, 6 and 2 respectively. The square bracket constructor begins with an opening '[' and ends with a closing ']'. A comma ',' is used to separate each member in the array.
 
Curly bracket array constructor
array{5, 10, 6, 2}
  • This array declaration uses a curly bracket array constructor to create an array of four integer values 5, 10, 6 and 2 respectively. The curly bracket constructor begins with the keyword 'array' followed by '{' and ending with a closing '}'. A curly bracket constructor can use an XPath statement to create its members, whereas a square bracket constructor cannot (this will be demonstrated in the array examples at the end of this section).
 
array{5, 10, 6, 2}(2)
result:  10
  • Parentheses containing an integer value can be used for array lookups. The first member of the array is in position 1. This example looks up the second member of the array which in this case is the integer 10. If the lookup attempts to retrieve from an index which is larger than the size of the array a dynamic error is raised.
 



 


7.1.1   Built-in Array Functions 



XPath 3.1 contains a number of built-in utility functions for arrays:


 array:size()

 array:get()

 array:append()

 array:subarray()

 array:remove()

 array:insert-before()

 array:head()

 array:tail()

 array:reverse()

 array:join()

 array:for-each()

 array:filter()

 array:fold-left()

 array:fold-right()

 array:for-each-pair()

 array:sort()

 array:flatten()

 


7.1.1.1  array:size()


The 'array:size' function returns the number of members in the array.

array:size(['Austria', 'Belgium', 'Canada'])
result:  3
  • In this example the array ['Austria', 'Belgium', 'Canada'] is passed to the 'array:size' function. As there are three members, the integer 3 is returned.
 
array:size(['Austria', 'Belgium', 'Canada', ['Denmark', 'Estonia']])
result:  4
  • In this example an array which contains strings and a nested array (['Austria', 'Belgium', 'Canada', ['Denmark', 'Estonia']]) is passed to the 'array:size' function. The result is 4 because the 4th member is itself an array.
 
 


7.1.1.2  array:get()


The first argument to the 'array:get' function supplies the array, the second argument is the index of the member to be retrieved from the supplied array.

array:get(['Austria', 'Belgium', 'Canada', ['Denmark', 'Estonia']], 2)
result:  'Belgium'
  • In this example the second member of the array is retrieved i.e. 'Belgium'.
 
 


7.1.1.3  array:append()


The 'array:append' function returns an array containing all members in the array supplied as the first argument plus an additional member consisting of the item supplied as the second argument.

array:append([10, 5, 8, 7], 4)
result:  [10, 5, 8, 7, 4]
  • In this example a new array is returned consisting of the members in the array passed as the first argument i.e. 10, 5, 8, 7 and the value 4 appended as an additional member.
 
 


7.1.1.4  array:subarray()


The 'array:subarray' function returns all members from the array supplied as the first argument, starting from a position supplied as the second argument up to the specified length supplied as an optional third argument.

array:subarray(['Estonia', 'Russia', 'Germany', 'France', 'Sweden'], 2)
result:  ['Russia', 'Germany', 'France', 'Sweden']
  • In this example the 'array:subarray' function returns an array which contains the members of the array supplied at the first argument starting at position 2 i.e. an array with members 'Russia', 'Germany', 'France', 'Sweden'.
 
array:subarray(['Estonia', 'Russia', 'Germany', 'France', 'Sweden'], 3, 2)
result:  ['Germany', 'France']
  • In this example the 'array:subarray' function returns an array which contains the members of the array supplied as the first argument starting at position 3, up to length 2 i.e. an array with members 'Germany' and 'France'.
 
 


7.1.1.5  array:remove()


The 'array:remove' function returns an array containing all the members of the array supplied as the first argument except for the member supplied as the second argument.

array:remove(['Estonia', 'Russia', 'Germany', 'France', 'Sweden'], 3)
result:   ['Estonia', 'Russia', 'France', 'Sweden']
  • In this example the 'array:remove' function returns an array which contains all members of the array supplied as the first argument except for the third member ('Germany') specified by the index supplied as the second argument.
 
 


7.1.1.6  array:insert-before()


The 'array:insert-before' function returns an array containing all the members of the array supplied as the first argument with one additional member at the position supplied as the second argument.

array:insert-before(['Estonia', 'Russia', 'Germany', 'France', 'Sweden'], 3, 'Italy')
result:   ['Estonia', 'Russia', 'Italy', 'Germany', 'France', 'Sweden']
  • In this example the 'array:insert-before' function returns an array which contains all members of the array supplied as the first argument plus a member specified by the third argument which is inserted before the member specified by the index supplied as the second argument.
 
 


7.1.1.7  array:head()


The 'array:head' function returns the first member of the supplied array.

array:head(['Estonia', 'Russia', 'Germany', 'France', 'Sweden'])
result:  'Estonia'
  • In this example the 'array:head' function returns the first member of the supplied array i.e. 'Estonia'.
 
 


7.1.1.8  array:tail()


The 'array:tail' function returns an array containing all members of the supplied array except for the first member.

array:tail(['Estonia', 'Russia', 'Germany', 'France', 'Sweden'])
result:   ['Russia', 'Germany', 'France', 'Sweden']
  • In this example the 'array:tail' function returns an array containing all members of the supplied array except for the first member.
 
 


7.1.1.9  array:reverse()


The 'array:reverse' function returns an array containing all members of the supplied array in reverse order.

array:reverse(['Estonia', 'Russia', 'Germany', 'France', 'Sweden'])
result:   ['Sweden','France','Germany','Russia','Estonia']
  • In this example the 'array:reverse' function returns an array containing all members of the supplied array, but in reverse order.
 
 


7.1.1.10  array:join()


The 'array:join' function concatenates the contents of multiple arrays into one array.

array:join((['Australia', 'New Zealand'] , ['Brazil', 'Argentina']))
result:   ['Australia', 'New Zealand', 'Brazil', 'Argentina']
  • In this example the 'array:join' function returns an array containing the contents of the two arrays ['Australia', 'New Zealand'] and ['Brazil', 'Argentina'] i.e. ['Australia', 'New Zealand', 'Brazil', 'Argentina'].
 
 


7.1.1.11  array:for-each()


The 'array:for-each' function applies the function supplied as the second argument to each member of the array supplied as the first argument.

array:for-each(['Australia', 'New Zealand', 'Brazil', 'Argentina'] , lower-case(?))
result:   ['australia', 'new zealand', 'brazil', 'argentina']
  • In this example the 'lower-case' function is applied to each member of the array supplied to the 'array:for-each' function and an array of the same size is returned.
 
 


7.1.1.12  array:filter()


The 'array:filter' returns an array containing those members of the array supplied as the first argument for which the function supplied as the second argument returns 'true'.

array:filter(['Australia', 'New Zealand', 'Brazil', 'Argentina'] , contains(?, 'zil'))
result:   ['Brazil']
  • In this example because only one member in the supplied array contains the string 'zil' i.e. 'Brazil', an array of size one is returned by the 'array:filter' function.
 
 


7.1.1.13  array:fold-left()


The 'array:fold-left' function takes three arguments. The first argument is an array, the second argument is the base value and the third function is a function. 'array:fold-left' evaluates the supplied function cumulatively on successive values of the supplied array.

array:fold-left([1 , 2 , 3], 0, function($a, $b){$a - $b})
result:  -6
  • In this example 'fold-left' takes a function which operates on a pair of values '$a' and '$b'. 'fold-left' applies the function supplied repeatedly, with an accumulated result as the first argument '$a', and the next item in the supplied array as the second argument '$b'. The accumulated result is initially set to the base value which in this case is 0. The example above evaluates to (((0 - 3) - 2) - 1) i.e. -6
 
 


7.1.1.14  array:fold-right()


The 'array:fold-right' function takes three arguments. The first argument is an array, the second argument is the base value and the third function is a function. 'array:fold-right' evaluates the supplied function cumulatively on successive values of the supplied array.

array:fold-right([1 , 2 , 3], 0, function($a, $b){$a - $b})
result:  2
  • In this example 'fold-right' takes a function which operates on a pair of values '$a' and '$b'. 'fold-right' applies the function supplied repeatedly, with the next item in the supplied array as the first argument '$a', and the accumulated result as the second argument '$b'. The accumulated result is initially set to the base value, which in this case is 0. The example above evaluates to (1 - (2 - (3 - 0 ))) i.e. 2
 
 


7.1.1.15  array:for-each-pair()


The 'array:for-each-pair' function returns an array which is obtained by evaluating the function supplied as the third argument for each pair of members at the same position in the arrays supplied as the first and second arguments.

array:for-each-pair([ 1, 2, 3, 4] , [ 5, 10, 20, 40] , function($a, $b) {$a * $b})
result:   [5, 20, 60, 160]
  • In this example the function $a * $b is applied to each pair of members at the same position in the first and second arrays i.e. 1*5, 2*10, 3*20, 4*40, and the resulting array is returned i.e. [5, 20, 60, 160].
 
 


7.1.1.16  array:sort()


The 'array:sort' function returns an array containing all the members of the supplied array sorted according to a sort key function. 'array:sort' has two signatures: The first signature contains only one argument which supplies an array. The second signature contains a second argument which is used to supply a function according to which the array members should be sorted. The one signature function is equivalent to calling the two argument function with the 'fn:data#1' function i.e. it sorts the values according to their typed value.

array:sort([8 , 4 , 1 , 2])
result:   [1 , 2 , 4 , 8]
  • In this example supplied array of integers is sorted (in ascending order) and an array with the sorted integer values is returned.
 
array:reverse(array:sort([8 , 4 , 1 , 2]))
result:   [8 , 4 , 2 , 1]
  • In this example the function call in the last example is supplied as an argument to the 'array:reverse' function resulting in an array with the integer members sorted in descending order.
 
array:sort(['d' , 'b' , 'a' , 'c'])
result:   ['a' , 'b' , 'c', 'd']
  • In this example the supplied array of strings is sorted and an an array with the sorted string values is returned.
 
array:sort(['d' , 'b' , 'a' , 2 , 'c'])
result:   error cannot compare xs:integer with xs:string
  • In this example the array supplied to the 'array:sort' function contains string and integer members. This results in the function returning an error because it is not possible to compare integers and strings and therefore not possible sort the members of the supplied array.
 
array:sort(['d' , 'b' , 'a' , 2 , 'c'], string(?))
result:   [2, 'a', 'b', 'c', 'd']
  • In this example the array supplied to the 'array:sort' function contains string and integer members. The second argument is the 'string' function which casts each member in the supplied array to a string before attempting to sort.
 
 


7.1.1.17  array:flatten()


The 'array:flatten' function builds a new sequence from all items found in the input sequence and arrays.

array:flatten((1, 2, [3, 4]))
result:  (1, 2, 3, 4)
  • In this example the array [3, 4] which is the third item in the sequence (1, 2, [3, 4]) is replaced by the members of the array and the resulting sequence i.e. (1, 2, 3, 4) is returned.
 





Array Examples













[/company/office/employee/last_name]

result: 
 [('Smith', 'Jones', 'Brown', 'Davis', 'Mason')]
This square bracket array constructor constructs an array of one member. The member of the array is the sequence of 'last_name' element values.


array{/company/office/employee/last_name}

result: 
 ['Smith', 'Jones', 'Brown', 'Davis', 'Mason']
This curly bracket array constructor constructs an array with several members, each member is an item from the sequence of values which the XPath expression '/company/office/employee/last_name' evaluates to.


[/company/office/employee/last_name](1)

result: 
 ('Smith', 'Jones', 'Brown', 'Davis', 'Mason')
This expression returns the first member of the array constructed from the square bracket array constructor '[/company/office/employee/last_name]' .


array{/company/office/employee/last_name}(1)

result: 
 'Smith'
This expression returns the first member of the array constructed from the curly bracket array constructor 'array{/company/office/employee/last_name}' .


[/company/office/employee/last_name](2)

result: 
 Error: Index out of Range
This expression attempts to return the second member of the array but throws an error as there is only one member in the array.


array{/company/office/employee/last_name}(2)

result: 
 'Jones'
This expression returns the second member of the array i.e. 'Jones'.


array:for-each(array{/company/office/employee}, upper-case(?))

result: 
 ['JOHN SMITH 25', 'JOHN JONES 30', 'MARY BROWN 30', 'PETER DAVIS 34', 'MARK MASON 44']
This expression applies the function supplied in the second argument to each member of the array supplied in the first argument. The 'upper-case' function is applied to all subelements of the 'employee' element members.








7.2    Maps




Maps contain a collection of key / value pairs known as entries.

A map is constructed using the 'map' keyword followed by an opening curly bracket '{' and ending with a closing curly bracket '}'. The key / value pairs consist of the key followed by a colon ':' followed by the associated key value. Each 'entry' is separated by a comma ',' .

Maps can also be nested i.e. a map can contain another map.


map {'USA' : 'United States', 'CHN' : 'China', 'GER' : 'Germany'}
  • This map constructor creates a map with 3 key / value pairs.

 



 


7.2.1   Built-in Map Functions 



XPath 3.1 contains a number of built-in utility functions for maps:


 map:size()

 map:get()

 map:put()

 map:merge()

 map:keys()

 map:contains()

 map:entry()

 map:remove()

 map:for-each()

 


7.2.1.1  map:size()


The 'map:size' function returns the number of entries in the supplied map.

map:size( map { 'USA' : 'United States', 'CHN' : 'China', 'GER' : 'Germany' })
result:  3
  • In this example the supplied map has 3 entries and therefore the 'map:size()' function returns 3.
 
 


7.2.1.2  map:get()


The first argument to the 'map:get' function is the supplied map, the second argument is the supplied key for which the associated value is to be retrieved.

map:get( map { 'USA' : 'United States', 'CHN' : 'China', 'GER' : 'Germany' }, 'CHN' )
result:  'China'
  • In this example the associated value of the 'CHN' key i.e. 'China' is retrieved from the supplied map.
 
 


7.2.1.3  map:put()


The 'map:put' function returns a new map containing all members of the map supplied as the first argument replacing the associated value of the key supplied in the second argument with the value supplied in the third argument (if that key exists in the supplied map), or adding an additional key / value pair if the key specified in the second argument does not already exist in the supplied map.

map:put(map{'a' : 'anton', 'b' : 'bob', 'c' : 'carl'} ,  'a', 'andy')
result:  map{'a' : 'andy', 'b' : 'bob', 'c' : 'carl'}
  • In this example the key specified as the second argument i.e. 'a' exists in the supplied map and therefore 'map:put' returns a map which contains the same members as the supplied map except for the value of the key supplied as the second argument whose value is replaced by the value supplied as the third argument i.e. 'andy' .
 
map:put(map{'a' : 'anton', 'b' : 'bob', 'c' : 'carl'} ,  'd', 'dave')
result:  map{'a' : 'anton', ' b' : 'bob', ' c' : 'carl', 'd' : 'dave'}
  • In this example the key specified as the second argument i.e. 'd' does not exist in the supplied map and therefore the 'map:put' function returns a map which contains the same members as the supplied map plus an additional entry with the key and associated value specified by the second and third arguments of the 'map:put' function i.e. 'd' and 'dave' .
 
 


7.2.1.4  map:merge()


The 'map:merge' returns a new map with the entries from a number of existing maps.

map:merge((map{'a' : 'anton', 'b' : 'bob', 'c' : 'carl'} , map{'d' : 'dave', 'e' : 'earl' }, map{ 'a' : 'anna', 'd' : 'diane' }))
result:  map{'a' : 'anna', 'b' : 'bob', 'c' : 'carl', 'd' :'diane', e:'earl'}
  • In this example the 'map:merge' function takes three maps and returns a new map which contains the entries from the supplied sequence of maps. Because the first and third maps supplied both have members with a key of 'a', the value of the 'latter' map is used to construct the return map i.e. the map returned by the function will contain the value 'anna' as opposed to 'anton'. Likewise the second and third maps both have the key 'd', so the value 'diane' will appear in the returned map as opposed to 'dave'.
 
 


7.2.1.5  map:keys()


The 'map:keys' function returns an sequence of all keys in the supplied map.

map:keys(map{'a' : 'anton', 'b' : 'bob', 'c' : 'carl'})
result:  ('a', 'b', 'c')
  • In this example the 'map:keys' function returns an sequence which contains all of the keys in the supplied map i.e. ('a', 'b', 'c')
 
 


7.2.1.6  map:contains()


The 'map:contains' function tests whether the map supplied as the first argument contains an entry for the key which is specified as the second argument to the function.

map:contains(map{'a' : 'anton', 'b' : 'bob', 'c' : 'carl'} , 'a')
result:  true
  • In this example the 'map:contains' function checks to see whether there is an entry corresponding to the key 'a' in the supplied map.
 
map:contains(map{'a' : 'anton', 'b' : 'bob', 'c' : 'carl'} , 'd')
result:  false
  • In this example the 'map:contains' function checks to see whether there is an entry corresponding to the key 'd' in the supplied map.
 
 


7.2.1.7  map:entry()


The 'map:entry' function returns a map with one entry (key / value pair).

map:entry( 1 : 'John Smith' )
result:  map{ 1 : 'John Smith'}
  • In this example the 'map:entry' function returns a map with one entry i.e. the key 1 and the associated value 'John Smith'.

The examples at the end of this section will demonstrate creating a map dynamically using the 'map:merge' and 'map:entry' functions.
 
 
 


7.2.1.8  map:remove()


The 'map:remove()' function returns a map containing all entries of the supplied map except for the one specified by the supplied member as the second argument

map:remove(map{1 : 'Estonia', 2 : 'Russia', 3 : 'Germany', 4 : 'France', 5 : 'Sweden'} , 4)
result:  map{1 : 'Estonia', 2 : 'Russia', 3 : 'Germany', 5 : 'Sweden'}
  • In this example the 'map:remove' function returns a map containing all entries of the supplied map except for the entry identified by the key supplied as the second argument i.e. 4.
 
 


7.2.1.9  map:for-each()


The 'map:for-each' function returns a sequence of items by applying the function supplied as the second argument to each entry of the map supplied as the first argument.

map:for-each(map{1 : 'Estonia', 2 : 'Russia', 3 : 'Germany', 4 : 'France', 5 : 'Sweden'}, function($a, $b){upper-case($b) } )
result:   ('ESTONIA' , 'RUSSIA' , 'GERMANY' , 'FRANCE' , 'SWEDEN')
  • In this example the 'map:for-each' function applies the 'upper-case' function to the value of each entry in the map supplied as the first argument and returns the sequence ('ESTONIA' , 'RUSSIA' , 'GERMANY' , 'FRANCE' , 'SWEDEN').
 





Map Examples













map{ 
'Boston' : /company/office[@location='Boston']/employee/last_name/string() ,
'Vienna' : /company/office[@location='Vienna']/employee/last_name/string()
}

result: 
 {Boston:('Smith', 'Jones'), Vienna:('Brown', 'Davis', 'Mason')}
This map constructor uses an XPath expression to return a sequence of 'last_name' elements for the employees of the 'Boston' and 'Vienna' offices. The associated values of the 'Boston' and 'Vienna' keys are the sequences ('Smith' , 'Jones') and ('Brown', 'Davis' , 'Mason') respectively.


map:size(map{ 
'Boston' : /company/office[@location='Boston']/employee/last_name/string()  ,
'Vienna' : /company/office[@location='Vienna']/employee/last_name/string() 
})

result: 
 2
In this example there are 2 entries in the supplied map.


map:get(map{ 
'Boston' : data(/company/office[@location='Boston']/employee/last_name) ,
'Vienna' : data(/company/office[@location='Vienna']/employee/last_name)
} , 'Vienna')

result: 
 ('Brown', 'Davis', 'Mason')
In this example the value corresponding to the 'Vienna' key is returned. The value in this case is the sequence of strings 'Brown' , 'Davis' and 'Mason'.


map{ 
'Boston' : data(/company/office[@location='Boston']/employee/last_name) ,
'Vienna' : data(/company/office[@location='Vienna']/employee/last_name)
}('Vienna')

result: 
 ('Brown', 'Davis', 'Mason')
In this example the value corresponding to the 'Vienna' key is returned from the supplied map. This example is the same as the previous example but an alternate syntax is used for the lookup which does not require for the 'map:get' function to be explicitly called.


map:merge(for $i in //employee return map:entry($i/@id, $i/last_name))

result: 
 map {1B:Smith, 1V:Brown, 2B:Jones, 2V:Davis, 3V:Mason}
In this example an XPath statement consisting of a 'for' loop used to iterate over all 'employee' nodes and construct map entries is passed to the 'map:merge' function. The 'map:entry' function is called for each iteration: the value of the 'id' attribute of the 'employee' element is used as the map entry key and the value of the 'last_name' element is the associated value for that key. The 'map:merge' function constructs a map from all constructed map entries. In this way it is possibly to dynamically construct a map.








7.3    JSON




JSON stands for JavaScript Object Notation. It is a data interchange format which is gaining in popularity. XPath 3.1 includes two functions to process JSON data.


 


7.3.1   Built-in JSON Functions 



XPath 3.1 contains two built-in functions to process json data.


 parse-json()

 json-doc()

 


7.3.1.1  parse-json()


The 'parse-json' function parses a string supplied in JSON format and typically returns a map or array. The 'parse-json' function has two signatures, a one argument signature in which only the string to be parsed is supplied, and a two argument function where the first argument is the supplied string and the second argument is a map of options which can be used to parse the supplied string.

parse-json('{"employees" : {"employee" : {"id": 1, "name": "Chris", "age": 41}}}')
result:  map {"employees" : map {"employee" : map {"age" : 41, "id" : 1 , "name" : 'Chris'}}}
  • In this example the 'parse-json' function returns a map which contains a nested map. The nested map in turn contains another nested map.
 
 


7.3.1.2  json-doc()


The 'json-doc' function reads an external resource containing JSON, and returns the result of parsing the resource as JSON using the 'parse-json' function. The 'json-doc' function has two signatures, the one signature version supplies the url from which the json should be read and the two argument version supplies a map of options to be used when parsing the JSON data.

json-doc('http://blahblah/employees.json')
result:  map {"employees" : map {"employee" : map {"age" : 41, "id" : 1 , "name" : 'Chris'}}}
  • Assuming that the JSON text passed to the 'parse-json' function in the previous example is available at the url 'http://blahblah/employees.json', the result of calling json-doc('http://blahblah/employees.json') would be the same as passing the JSON string to the 'parse-json' function.
 







7.4    Other new XPath 3.1 Features




In addition to the new map, array and JSON features, XPath 3.1 also contains new built-in functions and operators.


 


7.4.1   New XPath 3.1 Operators 



The following list contains the new operators in XPath 3.1:


 Lookup operator

 Arrow operator

 


7.4.1.1  Lookup operator


The lookup operator i.e. '?' is used to retrieve array members located at a specified position in an array, or map values associated with a specific key in a map. The lookup operator is followed by a specifier.

The specifier can be the integer offset of an array, the name of a key (in a map), a wildcard value, or any other parenthesized expression.

map{1: 'a', 2: 'b', 3: 'c'}?2
result:  'b'
  • In this example the supplied lookup operator is followed by the integer 2 which retrieves the associated value of the key 2 in the map i.e. 'b'
 
map{1: 'a' ,  2: 'b' , 3: 'c'}?*
result:  ('a' , 'b' , 'c')
  • In this example the supplied lookup operator is followed by the wildcard '*' character i.e. '*' . The wildcard retrieves the associated values of all keys in the map
 
let $x := parse-json('{"employees" : {"employee" : {"id": 1, "name": "Chris", "age": 41}}}')
return $x?employees?employee?age
result:  41
  • In this example the 'parse-json' function returns a map which contains nested maps. The 'lookup' operator is used numerous times to access the associated values of keys in the nested maps i.e. ?employees?employee?age
 
array{'x' , 'y' , 'z'}?1
result:  'x'
  • In this example the supplied lookup operator is followed by the integer 1 which retrieves the associated member at index 1 in the array i.e. 'x'.
 
array{'x' , 'y' , 'z'}?*
result:  ('x' , 'y' , 'z')
  • In this example the supplied lookup operator is followed by '*' which retrieves all members in the array.
 
 


7.4.1.2  Arrow operator


The arrow operator i.e. '=>' applies a function to a value. The value is used as the first argument to the function.The arrow is followed by the function to be called.

'hello goodbye hallo gutentag' => tokenize() => sort() => string-join(' ')
result:  'goodbye gutentag hallo hello'
  • In this example the string is passed as the first argument to the 'tokenize' function. The sequence of tokens is then passed as the first argument to the 'sort' function. Once the sequence of tokens has been sorted, the 'string-join' funciton is called with the sequence of tokens as the first argument and a space i.e. ' ' as the second argument resulting in a string of sorted values separated by spaces.
 
string-join(sort(tokenize('hello goodbye hallo gutentag')), ' ' )
result:  'goodbye gutentag hallo hello'
  • This example uses the 'conventional syntax' to call the 'tokenize', 'sort' and 'string-join' functions. Comparing the conventional function calls with the function calls indicated by the arrow operator shows that the XPath expression which uses the arrow operator is easier to read and understand.
 
 


7.4.2   New XPath 3.1 Functions 



The following list contains some of the interesting new additions to the built-in function library of XPath 3.1


 contains-token()

 parse-ietf-date()

 random-number-generator()

 sort()

 


7.4.2.1  contains-token()


This function is a boolean function which determines whether any of the strings supplied in the first argument when tokenized at whitespace boundaries contain the token supplied as the second argument .The 'contains-token' function has also has a three argument variation where the third argument is the collation.

contains-token(('hello', 'hello world'), 'world' )
result:  true
  • In this example the second string 'hello world' contains the token 'world' and therefore 'true' is returned.
 
contains-token(('hello', 'helloworld'), 'world' )
result:  false
  • In this example the token 'world' is not contained in any of the strings provided in the first argument.
 
 


7.4.2.2  parse-ietf-date()


Returns an 'xs:dateTime' value from the date supplied in 'ietf' format. Many HTML pages on the web use the ietf date format so this function is useful when retrieving data from HTML sources.

parse-ietf-date('Thu, 12 Mar 2015 09:40:00 GMT')
result:  xs:dateTime('2015-03-12T09:40:00Z')
  • This example parses the ietf value 'Thu, 12 Mar 2015 09:40:00 GMT' and returns the value '2015-03-12T09:40:00Z' of type 'xs:dateTime'.
 
 


7.4.2.3  random-number-generator()


The 'random-number-generator' function generates a random number. The function has two signatures: a zero argument signature, and a one argument signature. The one argument signature supplies a seed for calculating the random number.

The 'random-number-generator' function returns a map containing three entries: 'number', 'next' and 'permute'.

The associated value of 'number' is the random number i.e. an 'xs:double' value greater than or equal to zero i.e. 0.0e0 and less than one i.e. 1.0e0.

The associated value of 'next' is a zero-arity function that can be called to return another random number generator.

The associated value of 'permute' is a function with arity1 (one argument ), which takes an arbitrary sequence as its argument, and returns a random permutation of that sequence

random-number-generator()('number')
result:  xs:double(0.11688232421875)
  • This example calls the zero argument version of the 'random-number-generator' function and then filters the resulting map to return the associated value of the 'number' entry i.e. the random number generated by the function.
 
 


7.4.2.4  sort()


The 'sort' function sorts the supplied sequence of items.

The one argument version of the 'sort' function simply supplies a sequence of items to be sorted

The two argument version of the 'sort' function supplies a sequence of items to be sorted and a function to be applied to each item in the sequence. The sequence is sorted based on the results of applying the function to the members in the sequence.

fn:sort((-2, 3, 1))
result:  (-2, 1, 3)
  • In this example the sequence of integers is sorted in increasing order
 
fn:sort((-2, 3, 1), fn:abs#1)
result:  (1, -2, 3)
  • In this example the sequence of integers in the input sequence is sorted in increasing order based upon the results of applying the absolute function to each item in the sequence.