How Does XSLT 3.0 Parse and Transform JSON?

XSLT 3.0 natively bridges JSON and XML data formats using the built-in functions json-to-xml() and xml-to-json(). By mapping JSON structures directly to a standardized XML vocabulary and converting XML node trees back into valid JSON strings, XSLT 3.0 allows developers to parse, query, modify, and serialize JSON payloads without relying on external libraries or custom extension functions.

Understanding the XSLT 3.0 JSON-XML Architecture

The W3C XSLT 3.0 and XPath 3.1 specifications introduce native handling for JSON data by defining a strict XML schema under the namespace [http://www.w3.org/2005/xpath-functions](http://www.w3.org/2005/xpath-functions) (commonly bound to the prefix fn or j).

When converting JSON to XML, JSON data types map directly to specific XML elements:

Parsing JSON with json-to-xml()

The json-to-xml() function accepts a JSON string and returns an XML document node adhering to the standard JSON-XML schema.

Example: Converting JSON String to XML

Given the following JSON input:

{
  "title": "Data Pipeline",
  "items": [10, 20, 30],
  "active": true
}

Calling json-to-xml($jsonString) produces this XML tree:

<map xmlns="http://www.w3.org/2005/xpath-functions">
  <string key="title">Data Pipeline</string>
  <array key="items">
    <number>10</number>
    <number>20</number>
    <number>30</number>
  </array>
  <boolean key="active">true</boolean>
</map>

Once transformed into XML nodes, you can query and manipulate the data using standard XPath 3.1 and xsl:template matching rules.

<xsl:stylesheet version="3.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    expand-text="yes">

  <xsl:param name="jsonInput" as="xs:string"/>

  <xsl:template name="xsl:initial-template">
    <xsl:variable name="xmlDoc" select="json-to-xml($jsonInput)"/>
    <report>
      <title>{$xmlDoc/fn:map/fn:string[@key='title']}</title>
      <status>{$xmlDoc/fn:map/fn:boolean[@key='active']}</status>
      <total>{sum($xmlDoc/fn:map/fn:array[@key='items']/fn:number)}</total>
    </report>
  </xsl:template>

</xsl:stylesheet>

Serializing XML to JSON with xml-to-json()

The xml-to-json() function performs the inverse operation. It takes an XML node constructed according to the [http://www.w3.org/2005/xpath-functions](http://www.w3.org/2005/xpath-functions) schema and serializes it into a standard JSON string.

Customizing JSON Output

xml-to-json() accepts an optional second argument containing serialization options defined as an XPath 3.1 map:

<xsl:stylesheet version="3.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:fn="http://www.w3.org/2005/xpath-functions">

  <xsl:output method="text" encoding="UTF-8"/>

  <xsl:template match="/">
    <xsl:variable name="xmlPayload">
      <fn:map>
        <fn:string key="status">success</fn:string>
        <fn:array key="records">
          <fn:map>
            <fn:number key="id">101</fn:number>
            <fn:string key="name">Alpha</fn:string>
          </fn:map>
        </fn:array>
      </fn:map>
    </xsl:variable>

    <xsl:value-of select="xml-to-json($xmlPayload, map{'indent': true()})"/>
  </xsl:template>

</xsl:stylesheet>

Practical JSON-to-JSON Transformation Pipeline

Combining both functions allows XSLT stylesheets to operate purely as JSON-to-JSON transformations:

  1. Ingest raw JSON text via unparsed-text() or a stylesheet parameter.
  2. Convert the payload into an in-memory XML document using json-to-xml().
  3. Apply standard template rules (xsl:apply-templates) to modify nodes, add attributes, or filter data.
  4. Convert the modified XML document back into JSON format using xml-to-json().