The logo is a pig framed between two angle brackets.

XProc 3.0 Tutorial

Managing Key/Value Pairs With Maps

Many modern programming languages support collections of key/value pairs. Although the concepts slightly differ, they are named hash maps, associative arrays or dictionaries. XSLT 3.0 introduced an extension of XPath 3.0 called maps which was later officially added in XPath 3.1. A map is a function that associates a set of keys with values called map entries. For instance, we can describe a cup of ice cream as map:

map{
    'flavor'      : 'Very Cherry',
    'topping'     : 'Chocolate Cream',
    'cup-or-cone' : 'Cup'
    }

In XProc 3.0 serialization options, document properties and parameters are represented as maps. There are also XProc steps that require a map for certain options. For instance, you need to pass the HTTP headers for the step p:http-request as map. You can also declare options and variables in your pipeline as maps to make it easier to manage sets of key/value pairs.

Due to their similar data structure, maps are often required as a carrier for conversion to or from JSON. Let’s imagine that we are the owner of a virtual ice cream truck and our customers are used to place their orders in JSON. Of course we use XProc to serve the ice cream with delicious pointed brackets in XML. Please note that if you declare JSON documents inline, you need to double the curly braces because they are reserved for Attribute and Text Value Templates.

<?xml version="1.0" encoding="UTF-8"?>
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc" version="3.0">
  
  <p:input port="source">
    <p:inline document-properties="map{'content-type':'application/json'}">
      {{
        "flavor":"Very Cherry",
        "topping":"Chocolate Cream",
        "cup-or-cone":"Cup"
        }}
    </p:inline>
  </p:input>
  
  <p:output port="result" serialization="map{'indent':true()}"/>
  
  <p:identity>
    <p:with-input port="source" select="json-to-xml(.)"/>
  </p:identity>
  
</p:declare-step>

Output

<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
  <string key="flavor">Very Cherry</string>
  <string key="topping">Chocolate Cream</string>
  <string key="cup-or-cone">Cup</string>
</map>

Maps are used here for three tasks: Setting the document properties of the document at the input port, passing the serialization options to the output port and the XPath function json-to-xml() provides as result an XML representation of a map. This XML representation is required for the function xml-to-json() that provides the reverse operation.

Some steps have options that require a map like the parameters option in p:xslt. Here is an example how to pass a map to the this option:

<p:xslt>
  <p:with-input port="stylesheet" href="ice-cream-truck.xsl"/>
  <p:with-option name="parameters" 
                 select="map{
                             'flavor':'Very Cherry',
                             'topping':'Chocolate Cream',
                             'cup-or-cone':'Cup'
                             }"/>
</p:xslt>

Read more…