JSON Functions
These functions convert between JSON strings and the W3C XML representation of JSON, defined in namespace http://www.w3.org/2005/xpath-functions.
json-to-xml
json-to-xml($json as xs:string) as document-node()
json-to-xml($json as xs:string, $options as map(*)) as document-node()
Parses a JSON string and returns an XML document using the W3C JSON XML representation.
JSON to XML mapping
| JSON | XML element | Example |
|---|---|---|
| Object | <map> |
{"a": 1} → <map><number key="a">1</number></map> |
| Array | <array> |
[1, 2] → <array><number>1</number><number>2</number></array> |
| String | <string> |
"hello" → <string>hello</string> |
| Number | <number> |
42 → <number>42</number> |
| Boolean | <boolean> |
true → <boolean>true</boolean> |
| Null | <null/> |
null → <null/> |
Object keys are represented as key attributes: {"name": "Alice"} becomes <string key="name">Alice</string>.
Options
The optional $options map supports:
| Key | Type | Description |
|---|---|---|
escape |
xs:boolean |
When true, preserve JSON escape sequences and mark strings with escaped="true" |
Example
<xsl:variable name="data" select="json-to-xml('{ "name": "Alice", "age": 30 }')"/>
<!-- Result:
<map xmlns="http://www.w3.org/2005/xpath-functions">
<string key="name">Alice</string>
<number key="age">30</number>
</map>
-->xml-to-json
xml-to-json($input as node()) as xs:string
xml-to-json($input as node(), $options as map(*)) as xs:string
Converts an XML document in the W3C JSON XML representation back to a JSON string.
Example
<xsl:variable name="json-string" select="xml-to-json($xml-data)"/>
<!-- If $xml-data contains:
<map xmlns="http://www.w3.org/2005/xpath-functions">
<string key="name">Alice</string>
<number key="age">30</number>
</map>
Result: '{"name":"Alice","age":30}'
-->Round-trip example
A common pattern is parsing JSON, transforming the XML, and serializing back to JSON:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:j="http://www.w3.org/2005/xpath-functions"
expand-text="yes">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template name="main">
<xsl:variable name="input" expand-text="no">{"items": [1, 2, 3]}</xsl:variable>
<xsl:variable name="xml" select="json-to-xml($input)"/>
<xsl:variable name="transformed">
<xsl:apply-templates select="$xml"/>
</xsl:variable>
<out><xsl:value-of select="xml-to-json($transformed)"/></out>
</xsl:template>
<!-- Add a "count" field to the top-level map -->
<xsl:template match="j:map[not(@key)]">
<xsl:copy>
<xsl:apply-templates/>
<j:number key="count">{count(j:array[@key='items']/*)}</j:number>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>