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:
- Objects map to
<map> - Arrays map to
<array> - Key-value strings, numbers, and booleans map to
<string>,<number>, and<boolean> - Null values map to
<null> - Object property names are represented by the
keyattribute on child 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>Navigating and Transforming the Parsed XML
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:
indent: A boolean flag (true()orfalse()) to format output with whitespaceliberal: A boolean flag allowing non-standard JSON input parsing when supportedvalidate: A boolean flag to enforce strict validation against the JSON XML schema
<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:
- Ingest raw JSON text via
unparsed-text()or a stylesheet parameter. - Convert the payload into an in-memory XML document using
json-to-xml(). - Apply standard template rules (
xsl:apply-templates) to modify nodes, add attributes, or filter data. - Convert the modified XML document back into JSON format using
xml-to-json().