An implementation of XQuery 3.1's map:find function for eXist
xquery version "3.1"; | |
(:~ | |
: An implementation of XQuery 3.1's map:find function for eXist, which does not support it natively as of 3.4.0. | |
: | |
: @author Joe Wicentowski | |
: @see https://www.w3.org/TR/xpath-functions-31/#func-map-find | |
:) | |
module namespace mf="http://joewiz.org/ns/xquery/map-find"; | |
(:~ | |
: Searches the supplied input sequence and any contained maps and arrays for a map entry with the supplied key, and returns the corresponding values. | |
: @param $input An input sequence | |
: @param $key A key | |
: @returns An array containing the value of any entries found to have the key | |
: @see https://www.w3.org/TR/xpath-functions-31/#func-map-find | |
:) | |
declare function mf:map-find($input as item()*, $key as xs:anyAtomicType) as array(*) { | |
array { mf:map-find-recurse($input, $key) } | |
}; | |
(:~ | |
: A utility function that recurses through the input searching for map entries with the supplied key. | |
: @param $input An input sequence | |
: @param $key A key | |
: @return The value of any entries found to have the key | |
:) | |
declare %private function mf:map-find-recurse($input as item()*, $key as xs:anyAtomicType) as item()* { | |
for $i in $input | |
return | |
if ($i instance of array(*)) then | |
mf:map-find-recurse($i?*, $key) | |
else if ($i instance of map(*)) then | |
map:for-each($i, | |
function($k, $v) { | |
if ($k eq $key) then | |
$v | |
else | |
(), | |
mf:map-find-recurse($v, $key) | |
} | |
) | |
else () | |
}; |
xquery version "3.1"; | |
import module namespace mf="http://joewiz.org/ns/xquery/map-find" at "map-find.xqm"; | |
(:~ | |
: Tests for mf:map-find, drawn from examples in the XPath & XQuery 3.1 F&O spec for map:find | |
: | |
: @author Joe Wicentowski | |
: @see https://www.w3.org/TR/xpath-functions-31/#func-map-find | |
:) | |
let $responses := | |
[ | |
map { | |
0: "no", | |
1: "yes" | |
}, | |
map { | |
0: "non", | |
1: "oui" | |
}, | |
map { | |
0: "nein", | |
1: ("ja","doch") | |
} | |
] | |
let $inventory := | |
map { | |
"parts": [ | |
map { | |
"parts": [], | |
"name": "engine", | |
"id": "YW678" | |
} | |
], | |
"name": "car", | |
"id": "QZ123" | |
} | |
return | |
( | |
mf:map-find($responses, 0), | |
mf:map-find($responses, 1), | |
mf:map-find($responses, 2), | |
mf:map-find($inventory, "parts") | |
) |
xquery version "3.1"; | |
[ | |
["no","non","nein"], | |
["yes","oui","ja","doch"], | |
[], | |
[ | |
[ | |
map { | |
"parts": [], | |
"name": "engine", | |
"id": "YW678" | |
} | |
], | |
[] | |
] | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment