Sponsored

XSLT Reference

xsl:map

XSLT 3.0 element

Creates an XDM map from one or more xsl:map-entry children, enabling key-value data structures directly in XSLT 3.0 stylesheets.

Syntax
<xsl:map><xsl:map-entry .../></xsl:map>

Description

xsl:map is the instruction form for constructing an XDM map — an unordered collection of key-value pairs where keys are atomic values and values can be any XDM sequence. Maps were added to XDM in version 3.1 and are central to working with JSON in XSLT 3.0.

The instruction form xsl:map is an alternative to the XPath constructor map{key: value, ...}. Use the instruction form when you want to build a map from dynamic content using sequence constructors, loops, or conditional logic. You can mix xsl:map-entry children with xsl:if, xsl:for-each, and other instructions to build the map programmatically.

Maps are immutable but can be merged using XPath map:merge(). They are particularly useful as lookup tables, configuration objects passed to named templates, and intermediate data structures when generating JSON output via xsl:output method="json".

Keys must be atomic values and must be unique within a map. Attempting to add duplicate keys raises an error unless you use map:merge() with an appropriate duplicates option.

Attributes

xsl:map has no element-specific attributes. Its content must consist of xsl:map-entry instructions (and other XSLT instructions that produce map entries).

Examples

Building a lookup table from XML data

Input XML:

<?xml version="1.0" encoding="UTF-8"?>
<products>
  <product id="P001" price="19.99"/>
  <product id="P002" price="4.50"/>
  <product id="P003" price="129.00"/>
</products>

Stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:map="http://www.w3.org/2005/xpath-functions/map">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/products">
    <xsl:variable name="price-map">
      <xsl:map>
        <xsl:for-each select="product">
          <xsl:map-entry key="@id" select="xs:decimal(@price)"/>
        </xsl:for-each>
      </xsl:map>
    </xsl:variable>
    <prices>
      <item id="P001"><xsl:value-of select="map:get($price-map, 'P001')"/></item>
      <item id="P999"><xsl:value-of select="(map:get($price-map, 'P999'), 'N/A')[1]"/></item>
    </prices>
  </xsl:template>
</xsl:stylesheet>

Output:

<prices>
  <item id="P001">19.99</item>
  <item id="P999">N/A</item>
</prices>

Generating JSON output from a map

Stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xsl:output method="json" indent="yes"/>

  <xsl:template match="/products">
    <xsl:map>
      <xsl:map-entry key="'count'" select="count(product)"/>
      <xsl:map-entry key="'ids'">
        <xsl:sequence select="array{product/@id/string()}"/>
      </xsl:map-entry>
      <xsl:map-entry key="'generated'" select="string(current-dateTime())"/>
    </xsl:map>
  </xsl:template>
</xsl:stylesheet>

Notes

  • xsl:map produces a single map item, not a sequence of nodes. You cannot mix map entries and node constructors in the same xsl:map.
  • The XPath expression form map{k1: v1, k2: v2} is equivalent and more concise when the keys and values are known at compile time.
  • To merge two maps, use the XPath function map:merge(($map1, $map2)).
  • Maps are not serialised by default in XML output mode; to include them in output, convert to XML or use JSON output.

See also