#Map Functions
Maps are XPath's key-value data structure, introduced in XPath 3.1. If you work with Dictionary<TKey, TValue> in C# or JSON objects, maps are the XPath equivalent.
All map functions are in the map: namespace.
#Contents
#Construction
#Map Literals
Maps can be created with literal syntax:
map { "name": "Alice", "age": 30 }
map { 1: "one", 2: "two", 3: "three" }
map { } (: empty map :)C# equivalent:
new Dictionary<string, object> { ["name"] = "Alice", ["age"] = 30 }#map:merge()
Merges multiple maps into one. Later entries override earlier ones for duplicate keys.
Signature: map:merge($maps as map(*)*) as map(*)
map:merge((
map { "a": 1, "b": 2 },
map { "b": 3, "c": 4 }
))
=> map { "a": 1, "b": 3, "c": 4 }
C# equivalent: Multiple .Union() or ToDictionary calls with conflict resolution.
#map:entry()
Creates a single-entry map.
Signature: map:entry($key as xs:anyAtomicType, $value as item()*) as map(*)
map:entry("name", "Alice") => map { "name": "Alice" }#map:pair()
Creates a map from a key-value pair. New in XPath 4.0.
#map:of-pairs()
Creates a map from a sequence of key-value pair maps. New in XPath 4.0.
#map:build()
Builds a map from a sequence using key and value functions. New in XPath 4.0.
Signature: map:build($seq as item()*, $key as function(item()) as xs:anyAtomicType, $value as function(item()) as item()*) as map(*)
map:build(//book,
function($b) { $b/@isbn },
function($b) { $b/title/string() })
=> map { "978-0-123...": "Effective C#", "978-0-987...": "XML in a Nutshell" }
C# equivalent: books.ToDictionary(b => b.Isbn, b => b.Title)
#Access
#map:get()
Returns the value associated with a key.
Signature: map:get($map as map(*), $key as xs:anyAtomicType) as item()*
map:get(map { "name": "Alice", "age": 30 }, "name") => "Alice"
map:get(map { "name": "Alice" }, "email") => () (: missing key :)
Shorthand: The ? lookup operator:
$person?name => same as map:get($person, "name")
$person?age => same as map:get($person, "age")
C# equivalent: dict["name"] or dict.GetValueOrDefault("name")
#map:contains()
Tests whether a map contains a key.
Signature: map:contains($map as map(*), $key as xs:anyAtomicType) as xs:boolean
map:contains(map { "name": "Alice" }, "name") => true
map:contains(map { "name": "Alice" }, "email") => false
C# equivalent: dict.ContainsKey("name")
#map:size()
Returns the number of entries.
Signature: map:size($map as map(*)) as xs:integer
map:size(map { "a": 1, "b": 2 }) => 2
map:size(map { }) => 0
C# equivalent: dict.Count
#map:keys()
Returns all keys in the map.
Signature: map:keys($map as map(*)) as xs:anyAtomicType*
map:keys(map { "name": "Alice", "age": 30 }) => ("name", "age")
C# equivalent: dict.Keys
#map:empty()
Returns an empty map. New in XPath 4.0.
#Modification
Maps are immutable — these functions return new maps.
#map:put()
Returns a new map with an added or updated entry.
Signature: map:put($map as map(*), $key as xs:anyAtomicType, $value as item()*) as map(*)
map:put(map { "a": 1 }, "b", 2) => map { "a": 1, "b": 2 }
map:put(map { "a": 1 }, "a", 99) => map { "a": 99 } (: update :)
C# equivalent: With immutable dictionaries: dict.SetItem("b", 2)
#map:remove()
Returns a new map without the specified key.
Signature: map:remove($map as map(*), $key as xs:anyAtomicType) as map(*)
map:remove(map { "a": 1, "b": 2 }, "a") => map { "b": 2 }
C# equivalent: dict.Remove("a") (immutable version)
#map:replace()
Replaces a value by applying a function to the existing value. New in XPath 4.0.
#Iteration
#map:for-each()
Applies a function to each key-value pair, returning a sequence.
Signature: map:for-each($map as map(*), $fn as function(xs:anyAtomicType, item()*) as item()*) as item()*
map:for-each(
map { "name": "Alice", "age": 30 },
function($k, $v) { $k || "=" || $v }
)
=> ("name=Alice", "age=30")
C# equivalent: dict.Select(kv => $"{kv.Key}={kv.Value}")
#map:filter()
Returns a map containing only entries where the predicate is true. New in XPath 4.0.
Signature: map:filter($map as map(*), $fn as function(xs:anyAtomicType, item()*) as xs:boolean) as map(*)
map:filter(
map { "name": "Alice", "age": 30, "city": "NYC" },
function($k, $v) { $k != "age" }
)
=> map { "name": "Alice", "city": "NYC" }
C# equivalent: dict.Where(kv => kv.Key != "age").ToDictionary()
#map:entries()
Returns the entries of a map as a sequence of single-entry maps. New in XPath 4.0.
#map:group-by()
Groups a sequence into a map using a key function. New in XPath 4.0.
Signature: map:group-by($seq as item()*, $key as function(item()) as xs:anyAtomicType) as map(*)
map:group-by(//book, function($b) { $b/@category })
=> map {
"programming": (book1, book2),
"data": (book3)
}
C# equivalent: books.GroupBy(b => b.Category).ToDictionary(g => g.Key, g => g.ToList())
This is one of the most powerful XPath 4.0 additions — it turns a common multi-step operation into a single function call.
#map:keys-where()
Returns keys where a predicate on the value is true. New in XPath 4.0.