Maps and Arrays in XQuery 3.1

Maps and arrays (XPath Structured Data) make XQuery a JSON producer: build them with constructors, read them with the lookup operator (?key, ?2, ?*, and the unary ? inside predicates), pipe them with =>, and choose the json output method in the prolog. Run with BaseX 693,830 , which honors the query's own serialization options:

json-report.xq: a JSON report built from the catalog
(: Build a JSON report from the catalog with maps, arrays, lookups and arrows :)
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "json";
declare option output:indent "yes";
let $books := array {
  //book ! map { "id": string(@id), "title": string(title), "price": xs:decimal(.//price),
                "authors": array { contributor/name ! string() } }
}
return map {
  "sender": string(//sender),
  "premium": array { $books?*[?price ge 20]?id },
  "first-author": $books?1?authors?1,
  "first-titles": array { $books?*?title => sort() => subsequence(1, 3) }
}
Producing JSON with BaseX
basex -i booknest-catalog.xml json-report.xq
Output
{
  "sender": "BookNest Catalog Service",
  "premium": [
    "b2",
    "b3",
    "b6"
  ],
  "first-author": "Mara Ellison",
  "first-titles": [
    "Gardens in Glass",
    "Patterns of the Deep Web",
    "Salt and Saffron"
  ]
}

Every map value must be a single item to serialize as JSON, so sequences go inside array { }; without it BaseX stopped with SERE0023 ("Value has more than one item"). Saxon 726,956 's xquery wrapper from XML in the Data Pipeline sets !method=adaptive on the command line, which overrides the prolog option, and the output prefix must be declared. ?2 on a map looks up the key 2, not the second entry, so on string keys it returns nothing.


Version 3 1

XQuery 3.1 became a W3C Recommendation on 21 March 2017. It extends XQuery to support JSON as well as XML, adding maps and arrays to the data model along with new expressions and functions to work with them. XQuery 3.1 remains the current, full Recommendation-level version.

XQuery 4.0 is under active development by the W3C's XQuery and XSLT Extensions Community Group (QT4CG) as a Community Group draft. As of early 2026 it is not yet an official W3C Recommendation and continues to evolve; it builds on XPath 4.0 (see XPath), a superset of XPath 3.1 that adds native JSON support and many new functions.

Maps

A map is a sequence of key/value pairs. map:remove returns a new map with a key removed; map:merge combines several maps into one; a map is itself callable as a function of its key.
ch05-maps.xq
let $m1 := map {'abc':123, 1:'hello'},
     $m2 := map:remove($m1,'abc'),
     $m3 := map:merge (for $i in 1 to 5
                                    return map {$i: 'value'||$i})
return (map:keys($m1),
           $m1('abc'),
           deep-equal($m1,$m2))
Output
1 abc 123 false

Arrays

An array is an ordered sequence of members, each of which may itself be a sequence. Square-bracket notation [...] constructs an array whose members are its comma-separated expressions; the keyword form array {...} instead flattens each comma-separated expression's items into separate members.
ch05-arrays.xq
let $a := [(1,2),3],                            (: two members :)
     $b := array {1 to 2,3},                 (: three members :)
     $c := array:size($a),                     (: 2 :)
     $d := $b(1),                                 (: 1 :)
     $e := [1,2,3]=2,                           (: true :)
     $f := function ($x as xs:integer*){count($x)}
return $f([1 to 5])                              (: 5 :)
The unary lookup operator ? looks up map or array members: ?* returns all values, ?key or ?N returns the value for a given key or position, and ?(...) looks up several keys/positions at once.
ch05-lookup-operator.xq
let $m := map {'R':'red', 'G':'green', 'B':'blue'}
return ($m?*,                              (: red green blue :)
           map:keys($m) ! $m(.)      (: red green blue :)
           $m?R,                              (: red :)
           $m?2,                              (: green :)
           $m?('G',3))                       (: green blue :)

Arrow operator

The arrow operator => pipes the expression on its left as the first argument into the function call on its right, letting a chain of function calls read left to right instead of nesting.
ch05-arrow-operator.xq
'w e l c o m e'
=> upper-case() => tokenize() => string-join('-')
Output
W-E-L-C-O-M-E

Map and array functions

Selected functions added for maps and arrays, plus other functions introduced alongside JSON support: