With XQuery 3.1's support of JSON parsing and serialization, this package is no longer being maintained. You are strongly encouraged to migrate your code to XQuery 3.1. (For eXist users, an implementation of the
fn:json-to-xml
andfn:xml-to-json
functions, see https://gist.github.com/joewiz/d986da715facaad633db.)
An XQuery module for parsing and serializing JSON, originally written by John Snelson, with minor bug fixes applied, and packaged in the EXPath Package format for convenient installation in any XQuery implementation that supports it.
Snelson's original article is the official documentation. The information below focuses on how to install this module and get up and running. A table from Snelson's article about how each aspect of JSON is captured as XML is reproduced below.
The original module was designed for use with XQilla, but since it is written in pure XQuery 3.0, it is compatible with other XQuery 3.0 processors. It has been tested with eXist 2.0+.
You can download the core module from the src/content/
directory and import it in your own XQuery.
For many systems, it is more convenient to install the module as an EXPath Package (.xar file).
A pre-built package is available on the Releases page.
To build the source into a package, you will need Apache Ant.
To install the package, you need an implementation of XQuery that supports the EXPath Package system.
To install in eXist-db, clone this repository and run ant, which will construct an EXPath Archive (.xar) file in the project's build folder. Then install the package via the eXist-db Package Manager, or place it in eXist-db's 'autodeploy' folder.
import module namespace xqjson="http://xqilla.sourceforge.net/lib/xqjson";
Note that the original module used "xqilla" as the module's namespace prefix, but this module uses "xqjson" instead, and the original module used "http://xqilla.sourceforge.net/Functions" as the module's namespace, but this module has adopted the more specific "http://xqilla.sourceforge.net/lib/xqjson".
This function translates a valid JSON string into an XML representation.
Note: This function assumes that the JSON string supplied is valid JSON. If you encounter an error with this function, please check to make sure your JSON is valid using a free, online validator like jsonlint.com.
This function reverses the above process.
Note: The resulting JSON is not pretty-printed, and no effort is made to preserve whitespace when roundtripping from JSON to parsed XML back to serialized JSON.
This example shows how the parse-json()
function translates and captures JSON objects, arrays, strings, numbers, booleans, and nulls. (The JSON string was taken from wikipedia.)
let $json :=
'{
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 25,
"height_cm": 167.6,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
],
"children": [],
"spouse": null
}')
return
xqjson:parse-json($json)
This will return the following result:
<json type="object">
<pair name="firstName" type="string">John</pair>
<pair name="lastName" type="string">Smith</pair>
<pair name="isAlive" type="boolean">true</pair>
<pair name="age" type="number">25</pair>
<pair name="height_cm" type="number">167.6</pair>
<pair name="address" type="object">
<pair name="streetAddress" type="string">21 2nd Street</pair>
<pair name="city" type="string">New York</pair>
<pair name="state" type="string">NY</pair>
<pair name="postalCode" type="string">10021-3100</pair>
</pair>
<pair name="phoneNumbers" type="array">
<item type="object">
<pair name="type" type="string">home</pair>
<pair name="number" type="string">212 555-1234</pair>
</item>
<item type="object">
<pair name="type" type="string">office</pair>
<pair name="number" type="string">646 555-4567</pair>
</item>
</pair>
<pair name="children" type="array"/>
<pair name="spouse" type="null"/>
</json>
Using xqjson:serialize-json() on this <json>
element will return the original JSON, sans pretty printing:
{"firstName":"John","lastName":"Smith","isAlive":true,"age":25,"height_cm":167.6,"address":{"streetAddress":"21 2nd Street","city":"New York","state":"NY","postalCode":"10021-3100"},"phoneNumbers":[{"type":"home","number":"212 555-1234"},{"type":"office","number":"646 555-4567"}],"children":[],"spouse":null}
{
"firstName": "John"
}
<json type="object">
<pair name="firstName" type="string">John</pair>
</json>
{
"firstName": "John",
"lastName": "Smith",
"age": 25,
"isAlive": true
}
<json type="object">
<pair name="firstName" type="string">John</pair>
<pair name="lastName" type="string">Smith</pair>
<pair name="age" type="number">25</pair>
<pair name="isAlive" type="boolean">true</pair>
</json>
[
{
"label": "node1",
"children": [
"child1",
"child2"
]
},
{
"label": "node2",
"children": ["child3"]
}
]
<json type="array">
<item type="object">
<pair name="label" type="string">node1</pair>
<pair name="children" type="array">
<item type="string">child1</item>
<item type="string">child2</item>
</pair>
</item>
<item type="object">
<pair name="label" type="string">node2</pair>
<pair name="children" type="array">
<item type="string">child3</item>
</pair>
</item>
</json>
{
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
}
}
<json type="object">
<pair name="address" type="object">
<pair name="streetAddress" type="string">21 2nd Street</pair>
<pair name="city" type="string">New York</pair>
<pair name="state" type="string">NY</pair>
<pair name="postalCode" type="string">10021-3100</pair>
</pair>
</json>
{
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
]
}
<json type="object">
<pair name="phoneNumbers" type="array">
<item type="object">
<pair name="type" type="string">home</pair>
<pair name="number" type="string">212 555-1234</pair>
</item>
<item type="object">
<pair name="type" type="string">office</pair>
<pair name="number" type="string">646 555-4567</pair>
</item>
</pair>
</json>
{
"children": [],
"spouse": null
}
<json type="object">
<pair name="children" type="array"/>
<pair name="spouse" type="null"/>
</json>
JSON | type(JSON) | toXML(JSON) |
---|---|---|
JSON | N/A | <json type=" type(JSON)"> toXML(JSON)</json> |
{ "key1": value1, "key2": value2 } |
object | <pair name="key1" type=" type(value1)"> toXML(value1)</pair> <pair name="key2" type=" type(value2)"> toXML(value2)</pair> |
[ value1, value2 ] |
array | <item type=" type(value1)"> toXML(value1)</item> <item type=" type(value2)"> toXML(value2)</item> |
"value" |
string | value |
number | number | number |
true / false |
boolean | true / false |
null |
null | empty |
A test suite, written using the XQSuite framework for
eXist, can be run with the following command, assuming Apache Ant is installed (some properties in
build.xml
may need to be adapted to your system):
ant test
The result should show something like:
<testsuites>
<testsuite package="http://exist-db.org/xquery/test/xqjson"
timestamp="2014-12-16T01:39:11.326-05:00" failures="0" pending="0" tests="38" time="PT0.191S">
<testcase name="array-parse" class="xj:array-parse"/>
<testcase name="array-serialize" class="xj:array-serialize"/>
<!--more testcases...-->
</testsuite>
</testsuites>
If all is well, the @failures
attribute should read 0
.