How Do Maps and Arrays Work in XSLT 3.0?
XSLT 3.0 fundamentally expands the language beyond node trees and atomic sequences by introducing maps and arrays as first-class items. As first-class data structures, they can be stored in variables, passed into functions and templates, returned as results, and manipulated without serializing back into XML. This modern functional model bridges the gap between XML and JSON processing, enabling developers to build flexible, high-performance transformations for nested, heterogeneous, and non-XML datasets.
The First-Class Status of Maps and Arrays
In earlier versions of XSLT, sequences served as the only collection mechanism. However, standard sequences in XPath flatten automatically—a sequence of sequences simply becomes one flat sequence. This design prevented the nesting of multi-dimensional data structures.
With XPath 3.1 and XSLT 3.0, maps and arrays are treated as distinct
item types that belong to the item() hierarchy. Because an
array or map is a single item, putting an array inside another array
does not cause flattening.
Maps and arrays benefit from complete first-class support:
- Assignability: Can be assigned to variables
(
<xsl:variable>) and parameters (<xsl:param>). - Function Arguments and Returns: Can be passed into
or returned from XPath functions and XSLT functions
(
<xsl:function>). - Dynamic Typing: Supported by dedicated
type-checking expressions such as
map(*),map(xs:string, xs:integer),array(*), orarray(map(*)). - Higher-Order Function Integration: Function items,
maps, and arrays interact directly with functional combinators like
for-each,filter, andfold-left.
Working with Maps
A map in XSLT 3.0 is a collection of key-value pairs where keys are atomic values and values are arbitrary sequences.
Creation and Syntax
Maps can be constructed using literal syntax or constructor functions:
<!-- Literal Map Constructor -->
<xsl:variable name="user" select="map{
'id': 101,
'name': 'Alice',
'roles': ('admin', 'editor')
}" />
<!-- Function-based Map Constructor -->
<xsl:variable name="scores" select="map:merge((
map:entry('math', 95),
map:entry('science', 88)
))" />Accessing Map Data
Maps function syntactically as functions that take a key and return
the associated value. You can also use explicit functions or the lookup
operator (?):
<!-- Function-call syntax -->
<xsl:value-of select="$user('name')" />
<!-- Lookup operator syntax -->
<xsl:value-of select="$user?name" />
<!-- Standard library function -->
<xsl:value-of select="map:get($user, 'roles')" />Map Immutability
All map operations are purely functional and immutable. Functions
like map:put() and map:remove() do not modify
the original map in place; they return a new map reflecting the
changes:
<xsl:variable name="updatedUser" select="map:put($user, 'status', 'active')" />Working with Arrays
An array is an ordered list of zero or more members where each member can be an arbitrary sequence (including empty sequences or nested collections). Unlike standard sequences, arrays preserve internal nesting.
Creation and Syntax
Arrays use square brackets [...] for composite
constructors or curly braces array { ... } for flattening
constructors:
<!-- Square bracket constructor (preserves internal sequences as single members) -->
<xsl:variable name="matrix" select="[ [1, 2], [3, 4] ]" />
<!-- Flattening constructor (evaluates the expression and turns each item into a member) -->
<xsl:variable name="items" select="array { //book/@id }" />Accessing Array Members
Array indices are 1-based. Like maps, arrays act as functions that accept an integer index:
<!-- Function-call invocation -->
<xsl:value-of select="$matrix(1)(2)" /> <!-- Returns 2 -->
<!-- Lookup operator -->
<xsl:value-of select="$matrix?1?2" />
<!-- Unwrapping all members into a sequence -->
<xsl:sequence select="$matrix?*" />Array Manipulation
Functions in the array: namespace allow functional
additions, deletions, and transformations:
array:append($array, $member): Adds a member to the end.array:insert-before($array, $pos, $member): Inserts a member at the designated position.array:remove($array, $positions): Returns a new array with specified positions removed.array:for-each($array, $function): Applies a function to every member.
JSON Integration and Modern Data Processing
The inclusion of first-class maps and arrays enables bidirectional JSON processing without external libraries:
json-to-xml(): Converts a JSON string into an XSLT-native representation using XML elements, maps, or arrays.parse-json(): Directly parses a raw JSON string into native XSLT 3.0 maps and arrays.xml-to-json(): Converts an XML representation of JSON data into a valid JSON string.serialize()withmethod="json": Serializes XSLT maps and arrays straight into JSON text.
Through these structures, XSLT 3.0 serves as a full-featured data transformation engine capable of handling mixed XML, JSON, and in-memory key-value workflows efficiently.