JSON Module
This XQuery Module contains functions to parse and serialize JSON documents. JSON (JavaScript Object Notation) is a popular data exchange format for applications written in JavaScript. As there are notable differences between JSON and XML, no mapping exists that guarantees a lossless, bidirectional conversion between JSON and XML. For this reason, we offer two sets of functions in this module:
Contents
Conventions
All functions in this module are assigned to the http://basex.org/modules/json
namespace, which is statically bound to the json
prefix.
All errors are assigned to the http://basex.org/errors
namespace, which is statically bound to the bxerr
prefix.
JSON Functions
json:parse and json:serialize facilitate a lossless conversion from JSON to XML and back. The transformation is based on the following rules:
- The resulting document has a
<json/>
root node. - Names (keys) of objects are represented as elements:
- Empty names are represented by a single underscore (
<_>...</_>
). - Underscore characters are rewritten to two underscores (
__
). - A character that cannot be represented as NCName character is rewritten to an underscore and its four-digit Unicode.
- Empty names are represented by a single underscore (
- As the members of arrays have no names,
<value/>
is used as element name. - JSON values are represented as text nodes.
- The types of values are represented in attributes:
- The value types number, boolean, null, object and array are represented by a
type
attribute. - The string type is omitted, as it is treated as default type.
- If a name has the same type throughout the document, the
type
attribute will be omitted. Instead, the name will be listed in additional, type-specific attributes in the root node. The attributes are named by their type in the plural (numbers, booleans, nulls, objects and arrays), and the attribute value contains all names with that type, separated by whitespaces.
- The value types number, boolean, null, object and array are represented by a
json:parse
Version 7.7.2: $options
argument added
Signatures | json:parse($input as xs:string) as element(json) json:parse($input as xs:string, $options as item()) as element(json)
|
Summary | Converts the JSON document specified by $input to XML, and returns the result as element(json) instance. The converted XML document is both well readable and lossless, i.e., the converted document can be serialized back to the original JSON representation.The $options argument can be used to control the way the input is converted. The following options are available (they bear resemblance to the ones specified in XSLT 3.0):
Options can either be specified
<json:options> <json:format value='jsonml'/> ... </json:options>
{ 'format' : 'jsonml', ... } |
Errors | BXJS0001 : the specified input cannot be parsed as JSON document.BXJS0003 : a specified option cannot be parsed.
|
json:serialize
Signatures | json:serialize($input as node()) as xs:string json:serialize($input as node(), $options as item()) as xs:string
|
Summary | Serializes the node specified by $input as JSON, and returns the result as xs:string instance. The serialized node must conform to the syntax specified by the json:parse() function.XML documents can also be serialized as JSON if the Serialization Option "method" is set to "json" .The $options argument can be used to control the way the input is serialized. The following options are available (they bear resemblance to the ones specified in XSLT 3.0):
Options can either be specified
<json:options> <json:format value='jsonml'/> ... </json:options>
{ 'format' : 'jsonml', ... } |
Errors | BXJS0002 : the specified node cannot be serialized as JSON document.
|
Examples
Example 1: Adds all JSON documents in a directory to a database
Query:
let $database := "database" for $name in file:list('.', false(), '*.json') let $file := file:read-text($name) let $json := json:parse($file) return db:add($database, document { $json }, $name)
Example 2: Converts a simple JSON string to XML and back
Query:
json:parse('{}')
Result:
<json objects="json"/>
Query:
(: serialize result as plain text :) declare option output:method 'text'; json:serialize(<json objects="json"/>)
Result:
{ }
Example 3: Converts a JSON string with simple objects and arrays
Query:
json:parse('{ "title": "Talk On Travel Pool", "link": "http://www.flickr.com/groups/talkontravel/pool/", "description": "Travel and vacation photos from around the world.", "modified": "2009-02-02T11:10:27Z", "generator": "http://www.flickr.com/" }')
Result:
<json objects="json"> <title>Talk On Travel Pool</title> <link>http://www.flickr.com/groups/talkontravel/pool/</link> <description>Travel and vacation photos from around the world.</description> <modified>2009-02-02T11:10:27Z</modified> <generator>http://www.flickr.com/</generator> </json>
Example 4: Converts a JSON string with different data types
Query:
json:parse('{ "first_name": "John", "last_name": "Smith", "age": 25, "address": { "street": "21 2nd Street", "city": "New York", "code": 10021 }, "phone": [ { "type": "home", "number": "212 555-1234" }, { "type": "mobile", "number": 1327724623 } ] }')
Result:
<json numbers="age code" arrays="phone" objects="json address value"> <first__name>John</first__name> <last__name>Smith</last__name> <age>25</age> <address> <street>21 2nd Street</street> <city>New York</city> <code>10021</code> </address> <phone> <value> <type>home</type> <number>212 555-1234</number> </value> <value> <type>mobile</type> <number type="number">1327724623</number> </value> </phone> </json>
JsonML Functions
json:serialize-ml and json:parse-ml are used to transform XML to JSON and back, using the JsonML dialect. JsonML can be used to transform arbitrary XML documents, but namespaces, comments and processing instructions will be discarded in the transformation process. More details are found in the official JsonML documentation.
Version 7.7.2: the functions are now marked as deprecated. Please use json:parse and json:serialize and the { "format":"jsonml" }
option instead.
json:serialize-ml
Signatures | json:serialize-ml($input as node()) as xs:string
|
Summary | Serializes the node specified by $input and returns the result as xs:string instance.XML documents can also be output in the JsonML format by setting the Serialization Option "method" to "jsonml" .
|
Errors | BXJS0002 : the specified value cannot be serialized.
|
json:parse-ml
Signatures | json:parse-ml($input as xs:string) as element()
|
Summary | Converts the JsonML document specified by $input to XML, and returns the result as element() instance. The JSON input must conform to the JsonML specification to be successfully converted.
|
Errors | BXJS0001 : the specified input cannot be parsed as JsonML instance.
|
Examples
Example 1: Converts all XML documents in a database to JsonML and writes them to disk
Query:
for $doc in collection('json') let $name := document-uri($doc) let $json := json:serialize($doc) return file:write($name, $json)
Example 2: Converts a simple XML fragment to the JsonML format
Query:
json:serialize(<xml/>, { 'format': 'jsonml' })
Result:
["xml"]
Example 3: Converts an XML document with elements and text
Query:
json:serialize(doc('flickr.xml'), { 'format': 'jsonml' })
flickr.xml:
<flickr> <title>Talk On Travel Pool</title> <link>http://www.flickr.com/groups/talkontravel/pool/</link> <description>Travel and vacation photos from around the world.</description> <modified>2009-02-02T11:10:27Z</modified> <generator>http://www.flickr.com/</generator> </flickr>
Result:
["flickr", ["title", "Talk On Travel Pool"], ["link", "http:\/\/www.flickr.com\/groups\/talkontravel\/pool\/"], ["description", "Travel and vacation photos from around the world."], ["modified", "2009-02-02T11:10:27Z"], ["generator", "http:\/\/www.flickr.com\/"]]
Example 4: Converts a document with nested elements and attributes
Query:
json:serialize(doc('input.xml'), { 'format': 'jsonml' })
input.xml:
<address id='1'> <!-- comments will be discarded --> <last_name>Smith</last_name> <age>25</age> <address xmlns='will be dropped as well'> <street>21 2nd Street</street> <city>New York</city> <code>10021</code> </address> <phone type='home'>212 555-1234</phone> </address>
Result:
["address", {"id":"1"}, ["last_name", "Smith"], ["age", "25"], ["address", ["street", "21 2nd Street"], ["city", "New York"], ["code", "10021"]], ["phone", {"type":"home"}, "212 555-1234"]]
Errors
Code | Description |
---|---|
BXJS0001
|
The specified input cannot be parsed as JSON document. |
BXJS0002
|
The specified node cannot be serialized as JSON document. |
BXJS0003
|
A specified option cannot be parsed. |
Changelog
- Version 7.7.2
- Updated:
$options
argument added to json:parse and json:serialize - Updated: json:parse-ml and json:serialize-ml are now deprecated
The module was introduced with Version 7.0.