The saxon:tabulate-maps instruction selects a collection of maps and expands them by adding information from containing maps and arrays in a hierarchic structure (typically obtained by parsing JSON). The result is an array of maps which can be considered as a table with one row for each leaf in the tree, with data from upper levels of the hierarchy replicated in each relevant row of the table.

Category: instruction
Content: none
Permitted parent elements: any XSLT element whose content model is sequence-constructor; any literal result element




XPath expression selecting the root of a tree of maps and arrays.



XPath expression selecting a sequence of maps relative to the root of the tree.

Saxon availability

Requires Saxon-PE or Saxon-EE. Implemented since Saxon 9.9. Available for all platforms.


The effect of the instruction is easiest to illustrate by example. Consider the structure that results from parsing the JSON input:

[{ "country": "UK", "cities: [ { "name": "London", "population" : 7200000 }, { "name": "Birmingham", "population": 992000 }, { "name": "Leeds", "population": 720000 } ]}, { "country": "France" "cities": [ { "name": "Paris", "population" : 12341418 }, { "name": "Lyon", "population": 2214068 }, { "name": "Marseille", "population": 1727070 } ]} ]

This can be processed using the instruction:

<saxon:tabulate-maps root="parse-json($input)" select="?*?cities?*"/>

which delivers the result (serialized as JSON, with whitespace added for clarity):

[{"name":"London", "population":7.2E6, "_keys":[1,"cities",1], "country":"UK"}, {"name":"Birmingham", "population":992000, "_keys":[1,"cities",2], "country":"UK"}, {"name":"Leeds", "population":720000, "_keys":[1,"cities",3], "country":"UK"}, {"name":"Paris", "population":1.2341418E7, "_keys":[2,"cities",1], "country":"France"}, {"name":"Lyon", "population":2.214068E6, "_keys":[2,"cities",2], "country":"France"}, {"name":"Marseille", "population":1.72707E6, "_keys":[2,"cities",3], "country":"France"}]

The result is thus an array of maps, corresponding one-to-one with the maps selected in the select expression, with each map in the output containing:

  1. Copies of the entries (key-value pairs) in the original map
  2. Copies of all entries in containing maps, other than the containing entry
  3. A new entry, _keys, containing an array of map keys and array indexes representing a path from the root to the selected map.

If the added entries have key values that would conflict with existing entries, the key is modified by the addition of a numeric suffix.

The effect of the instruction is thus to create a flat structure (an array of maps) in which data from upper levels of the hierarchic structure is duplicated in each row of the result.

Stylesheets using saxon:tabulate-maps cannot be exported to SEF files.