Difference between revisions of "JSON Module"

From BaseX Documentation
Jump to navigation Jump to search
Line 31: Line 31:
 
|-
 
|-
 
| '''Summary'''
 
| '''Summary'''
|Converts the JSON document specified by {{Code|$input}} to XML, and returns the result as {{Code|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.<br/>The {{Code|$options}} argument can be used to control the way the input is converted. The following options are available (they bear resemblance to the one specified in [http://www.w3.org/TR/xslt-30/#json XSLT 3.0]):
+
|Converts the JSON document specified by {{Code|$input}} to XML, and returns the result as {{Code|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.<br/>The {{Code|$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 [http://www.w3.org/TR/xslt-30/#json XSLT 3.0]):
 
* {{Code|spec}} determines the used JSON specification. Allowed values are {{Code|RFC4627}}, {{Code|ECMA-262}}, and {{Code|liberal}}; the default is ({{Code|RFC4627}}).
 
* {{Code|spec}} determines the used JSON specification. Allowed values are {{Code|RFC4627}}, {{Code|ECMA-262}}, and {{Code|liberal}}; the default is ({{Code|RFC4627}}).
 
* {{Code|unescape}} determines whether escape sequences (marked by a backslash) in the input are expanded. The default is {{Code|true}}.
 
* {{Code|unescape}} determines whether escape sequences (marked by a backslash) in the input are expanded. The default is {{Code|true}}.
* {{Code|format}} determines the conversion format. Allowed values are {{Code|json}}, {{Code|jsonml}}, and {{Code|map}}; the default is {{Code|true}}.
+
* {{Code|format}} determines the conversion format. Allowed values are {{Code|json}}, {{Code|jsonml}}, and {{Code|map}}; the default is {{Code|json}}.
 
Options can either be specified<br />
 
Options can either be specified<br />
 
* as children of an {{Code|<json:options/>}} element; e.g.:
 
* as children of an {{Code|<json:options/>}} element; e.g.:
 
<pre class="brush:xml">
 
<pre class="brush:xml">
 
<json:options>
 
<json:options>
   <json:spec value='liberal'/>
+
   <json:format value='jsonml'/>
 
   ...
 
   ...
 
</json:options>
 
</json:options>
Line 45: Line 45:
 
* or as map, which contains all key/value pairs:
 
* or as map, which contains all key/value pairs:
 
<pre class="brush:xquery">
 
<pre class="brush:xquery">
{ 'spec' : 'liberal', ... }
+
{ 'format' : 'jsonml', ... }
 
</pre>
 
</pre>
 
|-
 
|-
Line 56: Line 56:
 
|-
 
|-
 
| width='120' | '''Signatures'''
 
| width='120' | '''Signatures'''
|{{Func|json:serialize|$input as node()|xs:string}}
+
|{{Func|json:serialize|$input as node()|xs:string}}<br/>{{Func|json:serialize|$input as node(), $options as item()|xs:string}}
 
|-
 
|-
 
| '''Summary'''
 
| '''Summary'''
|Serializes the node specified by {{Code|$input}} as JSON, and returns the result as {{Code|xs:string}} instance. The serialized node must conform to the syntax specified by the [[#json:parse|json:parse()]] function.<br />XML documents can also be serialized as JSON if the [[Serialization|Serialization Option]] {{Code|"method"}} is set to {{Code|"json"}}.
+
|Serializes the node specified by {{Code|$input}} as JSON, and returns the result as {{Code|xs:string}} instance. The serialized node must conform to the syntax specified by the [[#json:parse|json:parse()]] function.<br />XML documents can also be serialized as JSON if the [[Serialization|Serialization Option]] {{Code|"method"}} is set to {{Code|"json"}}.<br/>The {{Code|$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 [http://www.w3.org/TR/xslt-30/#json XSLT 3.0]):
 +
* {{Code|spec}} determines the used JSON specification. Allowed values are {{Code|RFC4627}}, {{Code|ECMA-262}}, and {{Code|liberal}}; the default is ({{Code|RFC4627}}).
 +
* {{Code|unescape}} determines whether escape sequences (marked by a backslash) in the input are expanded. The default is {{Code|true}}.
 +
* {{Code|format}} determines the conversion format. Allowed values are {{Code|json}}, {{Code|jsonml}}, and {{Code|map}}; the default is {{Code|json}}.
 +
Options can either be specified<br />
 +
* as children of an {{Code|<json:options/>}} element; e.g.:
 +
<pre class="brush:xml">
 +
<json:options>
 +
  <json:format value='jsonml'/>
 +
  ...
 +
</json:options>
 +
</pre>
 +
* or as map, which contains all key/value pairs:
 +
<pre class="brush:xquery">
 +
{ 'format' : 'jsonml', ... }
 +
</pre>
 
|-
 
|-
 
| '''Errors'''
 
| '''Errors'''

Revision as of 17:46, 24 September 2013

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:

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:

  1. The resulting document has a <json/> root node.
  2. Names (keys) of objects are represented as elements:
    1. Empty names are represented by a single underscore (<_>...</_>).
    2. Underscore characters are rewritten to two underscores (__).
    3. A character that cannot be represented as NCName character is rewritten to an underscore and its four-digit Unicode.
  3. As the members of arrays have no names, <value/> is used as element name.
  4. JSON values are represented as text nodes.
  5. The types of values are represented in attributes:
    1. The value types number, boolean, null, object and array are represented by a type attribute.
    2. The string type is omitted, as it is treated as default type.
    3. 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.

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):
  • spec determines the used JSON specification. Allowed values are RFC4627, ECMA-262, and liberal; the default is (RFC4627).
  • unescape determines whether escape sequences (marked by a backslash) in the input are expanded. The default is true.
  • format determines the conversion format. Allowed values are json, jsonml, and map; the default is json.

Options can either be specified

  • as children of an <json:options/> element; e.g.:
<json:options>
  <json:format value='jsonml'/>
  ...
</json:options>
  • or as map, which contains all key/value pairs:
{ '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):
  • spec determines the used JSON specification. Allowed values are RFC4627, ECMA-262, and liberal; the default is (RFC4627).
  • unescape determines whether escape sequences (marked by a backslash) in the input are expanded. The default is true.
  • format determines the conversion format. Allowed values are json, jsonml, and map; the default is json.

Options can either be specified

  • as children of an <json:options/> element; e.g.:
<json:options>
  <json:format value='jsonml'/>
  ...
</json:options>
  • or as map, which contains all key/value pairs:
{ '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

The module was introduced with Version 7.0.