Datypic Logo
XQuery

XQuery

Priscilla Walmsley (pwalmsley@datypic.com)

ISBN: 1491915102

2nd edition, 2015, O'Reilly Media, Inc.

Chapter 24: Maps, Arrays, and JSON

Please note that the book contains many inline examples and informal tables that are not provided here.

Example 24-1. A simple map constructor
xquery version "3.1";
map {
  "ACC": "Accessories",
  "WMN": "Women's",
  "MEN": "Men's"
}
Example 24-2. Nested maps
xquery version "3.1";
map {
    "ACC": map {
              "name": "Accessories",
              "code": 300 },
    "WMN": map {
              "name": "Women's",
              "code": 310 },
    "MEN": map {
              "name": "Men's",
              "code": 320 } 
    }
Example 24-3. Creating maps with map:entry and map:merge
xquery version "3.1";
declare namespace map = "http://www.w3.org/2005/xpath-functions/map";
map:merge(for $p in doc("catalog.xml")//product
          return map:entry(string($p/number), string($p/name)) )
Example 24-4. Map variables used in examples
xquery version "3.1";
declare variable $deptnames := map {
  "ACC": "Accessories",
  "WMN": "Women's",
  "MEN": "Men's"
};
declare variable $deptinfo := map {
  "ACC": map {
            "deptname": "Accessories",
            "deptnum": 300 },
  "WMN": map {
            "deptname": "Women's",
            "deptnum": 310 },
  "MEN": map {
            "deptname": "Men's",
            "deptnum": 320 } 
};
Example 24-5. Looking up a map value with a dynamic parameter
Query
xquery version "3.1";
declare variable $deptnames := map {
  "ACC": "Accessories",
  "WMN": "Women's",
  "MEN": "Men's"
};
for $prod in doc("catalog.xml")//product
return <product num="{$prod/number}" 
                dept-name="{$deptnames($prod/@dept)}"/>
Results
<product num="557" dept-name="Women's"/>
<product num="563" dept-name="Accessories"/>
<product num="443" dept-name="Accessories"/>
<product num="784" dept-name="Men's"/>
Example 24-6. Chaining map function calls
Query
xquery version "3.1";
declare variable $deptinfo := map {
  "ACC": map {
            "deptname": "Accessories",
            "deptnum": 300 },
  "WMN": map {
            "deptname": "Women's",
            "deptnum": 310 },
  "MEN": map {
            "deptname": "Men's",
            "deptnum": 320 } 
};
for $prod in doc("catalog.xml")//product
return <product num="{$prod/number}"
                dept-name="{$deptinfo($prod/@dept)("deptname")}"
                dept-code="{$deptinfo($prod/@dept)("deptnum")}"/>
Results
<product num="557" dept-name="Women's" dept-code="310"/>
<product num="563" dept-name="Accessories" dept-code="300"/>
<product num="443" dept-name="Accessories" dept-code="300"/>
<product num="784" dept-name="Men's" dept-code="320"/>
Example 24-7. Chaining map lookups
xquery version "3.1";
declare variable $deptinfo := map {
  "ACC": map {
            "deptname": "Accessories",
            "deptnum": 300 },
  "WMN": map {
            "deptname": "Women's",
            "deptnum": 310 },
  "MEN": map {
            "deptname": "Men's",
            "deptnum": 320 } 
};
for $prod in doc("catalog.xml")//product
return <product num="{$prod/number}"
                dept-name="{$deptinfo?($prod/@dept)?deptname}"
                dept-code="{$deptinfo?($prod/@dept)?deptnum}"/>
Example 24-8. Using map:for-each
Query
xquery version "3.1";
declare namespace map = "http://www.w3.org/2005/xpath-functions/map";
declare variable $deptnames := map {
  "ACC": "Accessories",
  "WMN": "Women's",
  "MEN": "Men's"
};
let $f := function($k, $v) 
  {concat('Key: ', $k, ', value: ', $v)}
return map:for-each($deptnames, $f)
Results
("Key: ACC, value: Accessories",
 "Key: WMN, value: Women's",
 "Key: MEN, value: Men's")
Example 24-9. Function that takes a map as an argument
Query
xquery version "3.1";
declare namespace map = "http://www.w3.org/2005/xpath-functions/map";
declare function local:large-keys
  ($maparg as map(xs:integer, item()*)) as xs:integer* {
   map:keys($maparg)[. > 50]
};
local:large-keys(map {10:"a", 55:"b", 60:"c"})
Results
(55, 60)
Example 24-10. Array variables used in examples
xquery version "3.1";
declare variable $array-of-ints := [10, 20, 30];
declare variable $array-of-arrays := [ ["a", "b", "c"], ["d", "e", "f"] ];
Example 24-11. Function that takes an array as an argument
xquery version "3.1";
declare namespace array = "http://www.w3.org/2005/xpath-functions/array";
declare function local:larger-values
  ($arrayarg as array(xs:integer))as xs:integer* {
   array:flatten($arrayarg)[. > 15]
};
local:larger-values([10, 20, 30])
Example 24-12. Serializing an XML element as JSON
Query
xquery version "3.1";
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; 
declare option output:method "json";
declare option output:indent "yes";
map {
   "number": 557,
   "props":
     <props>
       <length>31</length>
     </props>
}
Results
{
   "number": 557,
   "props":
     "<props>\n  <length>31</length>\n</props>"
}
Example 24-13. Comparing JSON to XML
JSON
{
   "number": 557,
   "name": "Fleece Pullover",
   "colorChoices": ["navy", "black"],
   "is-current": true,
   "other": null,
   "priceInfo": {
       "price": 19.99,
       "discount": 10.00
       }
}
Equivalent XML
<map xmlns="http://www.w3.org/2005/xpath-functions">
   <number key="number">557</number>
   <string key="name">Fleece Pullover</string>
   <array key="colorChoices">
      <string>navy</string>
      <string>black</string>
   </array>
   <boolean key="is-current">true</boolean>
   <null key="other"/>
   <map key="priceInfo">
      <number key="price">19.99</number>
      <number key="discount">10.00</number>
   </map>
</map>
Datypic XQuery Services