Map Functions

Maps are immutable: map:put(), map:remove() and map:merge() return new maps; map:get() (or $m?key), map:contains(), map:keys(), map:size(), map:entry(), map:find() and map:for-each() read them. Keys compare like eq (1 and 1.0 are one key, "1" another). Build a lookup table once and probe it often:

Lookup tables and grouping with map:merge
xp 'map:merge(//book ! map:entry(string(@id), string(title)))?b3' \
   'map:merge(//book ! map { string(published): string(@id) }, map { "duplicates": "combine" })' \
   'map { 1: "x", 1.0: "y" }'
Output
map:merge(//book ! map:entry(string(@id), string(title)))?b3 => "Salt and Saffron"
map:merge(//book ! map { string(published): string(@id) }, map { "duplicates": "combine" }) =>
  map{"2024":("b1","b6"),"2025":("b2","b5"),"2026":"b4","2023":"b3"}
map { 1: "x", 1.0: "y" }               => error XQDY0137

The duplicates option combine keeps all values for a shared key, grouping books by year in one expression (use-first is the default, reject fails). Key order is undefined in 3.1 (2026 precedes 2023 here), so never rely on it; the 4.0 draft makes maps keep insertion order.


Map Functions

Maps are collections of key/value entries, written with curly braces (e.g. {"a":1,"b":2}); like arrays, they were introduced in XPath 3.1. The map: functions below are evaluated against:
let $m := {"a":1,"b":2,3:"c"}
return …
map:get($m,3)c
map:contains($m,"b")true
map:keys($m)a b 3
map:size($m)3
map:put($m,4,"d"){"a": 1, "b": 2, "3": "c", "4": "d"}
map:remove($m,"a"){"b": 2, "3": "c"}
map:merge((map:entry("a",100), map:entry("b",200))){"a": 100, "b": 200}
map:find([$m,$m],"a")[1, 1]
map:for-each($m, function($k,$v){$k||$v})a1 b2 3c
ch03-map-functions.xpath.txt
merged-01-01-ch03-map-functions.xpath.txt
let $m := {"a":1,"b":2,3:"c"}
return map:get($m,3)
Output
c