Skip to content
JSON Functions

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('{ &quot;name&quot;: &quot;Alice&quot;, &quot;age&quot;: 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>