Changes

Jump to navigation Jump to search
1,347 bytes added ,  12:06, 2 July 2020
This [[Module Library|XQuery Module]] contains functions to parse and serialize JSON documents. data [httphttps://www.json.org/ JSON (JavaScript Object Notation)] is a popular data exchange format for applications written in JavaScript. As there are notable differences between JSON and XML, or XQuery data types, no mapping exists that guarantees a lossless, bidirectional conversion between JSON and XML. For this reason, we offer various mappings, all of which are suited to different use cases.
=Conventions=
All functions and errors in this module are assigned to the <code><nowiki>http://basex.org/modules/json</nowiki></code> namespace, which is statically bound to the {{Code|json}} prefix.<br/>All errors are assigned to the <code><nowiki>http://basex.org/errors</nowiki></code> namespace, which is statically bound to the {{Code|bxerr}} prefix.
==Conversion Formats==
 
'''A little advice''': in the Database Creation dialog of the GUI, if you select JSON Parsing and switch to the ''Parsing'' tab, you can see the effects of some of the conversion options.
===Direct===
The {{Code|direct}} conversion format allows a lossless conversion from JSON to XML and back. The transformation is based on the following rules:
* The resulting document has a {{Code|<json>}} root node. * Object pairs are represented via elements. The name of a pair is rewritten to an element name:** Empty names are represented by a single underscore ({{Code|_}}). Existing underscores are rewritten to two underscores ({{Code|__}})encoded, and characters that are not valid as described in element names are rewritten to an underscore and the character’s four-digit Unicode.** If the {{Code[[Conversion Module#Keys|lax}} option is set to {{Code|true}}Conversion Module]], invalid characters are simply replaced with underscores or (when invalid and used as first character of an element name) prefixed with an underscore. The resulting names are better readable, but cannot always be converted back to their original form.* Array entries are also represented via elements. , with {{Code|_}} is used as element name.
* Object and array values are stored in text nodes.
* The types of values are represented via {{Code|type}} attributes:
The {{Code|attributes}} format is lossless, too. The transformation based on the following rules:
* The resulting document has a {{Code|<json>}} root node. * Object pairs are represented via {{Code|<pair>}} elements. The name of a pair is stored in a {{Code|name}} attribute.* Array entries are represented via {{Code|<item>}} elements.
* Object and array values are stored in text nodes.
* The types of values are represented via {{Code|type}} attributes:
** The existing types are ''string'', ''number'', ''boolean'', ''null'', ''object'', and ''array''.
** As most values are strings, the ''string'' type is by default omitted.
 
===Map===
 
The {{Code|map}} format is lossless, too. It converts a JSON document to an XQuery map and vice versa. The conversion rules are the same as for [[XQuery 3.1#fn:parse-json|fn:parse-json]].
===Basic===
 
{{Mark|Introduced with Version 8.2}}:
The {{Code|basic}} format is another lossless format. It converts a JSON document to an XML node and vice versa. The conversion rules are the same as for [[XQuery 3.1#fn:json-to-xml|fn:json-to-xml]].
The {{Code|jsonml}} format is designed to convert XML to JSON and back, using the JsonML dialect. JsonML allows the transformation of arbitrary XML documents, but namespaces, comments and processing instructions will be discarded in the transformation process. More details are found in the official [http://jsonml.org/XML JsonML documentation].
'''A little advice''': in the Database Creation dialog of the GUI===XQuery=== The {{Code|xquery}} format is lossless, if you select too. It converts JSON Parsing data to an XQuery value (a map, array, string, number, boolean, or empty sequence) and switch to vice versa. The conversion rules are the ''Parsing'' tabsame as for [[XQuery 3.1#fn:parse-json|fn:parse-json]]. The resulting representation consumes less memory than XML-based formats, you and values can see the effects of some of the be directly accessed without conversion options. Thus, it is recommendable for very large inputs and for efficient ad-hoc processing.
==Options==
| {{Code|format}}
| Specifies the format for converting JSON data.
| {{Code|direct}}, {{Code|attributes}}, {{Code|jsonml}}, {{Code|mapxquery}}
| {{Code|direct}}
| ''parse'', ''serialize''
|- valign="top"
| {{Code|liberal}}
| Determines if minor deviations from [httphttps://www.rfc-editor.org/rfc/rfc7159.txt RFC 7159] will be ignored.
| {{Code|yes}}, {{Code|no}}
| {{Code|no}}
| {{Code|merge}}
| This option is considered when {{Code|direct}} or {{Code|attributes}} conversion is used:<br/>
* If a name has the same type throughout the documentdata, the {{Code|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 plural (''numbers'', ''booleans'', ''nulls'', ''objects'' and ''arrays''), and the attribute value contains all names with that type, separated by whitespaces.
| {{Code|yes}}, {{Code|no}}
| ''parse'', ''serialize''
|- valign="top"
| {{Code|unescapeescape}}
| Indicates if escaped characters are expanded (for example, {{Code|\n}} becomes a single {{Code|x0A}} character, while {{Code|\u20AC}} becomes the character {{Code|€}}).
| {{Code|yes}}, {{Code|no}}
| ''serialize''
|}
 
The JSON function signatures provide an {{Code|$options}} argument. Options can either be specified
* as children of an {{Code|<json:options/>}} element; e.g.:
<pre class="brush:xml">
<json:options>
<json:format value='direct'/>
...
</json:options>
</pre>
* or as map, which contains all key/value pairs:
<pre class="brush:xquery">
map { 'format': 'direct', ... }
</pre>
=Functions=
|-
| width='120' | '''Signatures'''
|{{Func|json:parse|$input string as xs:string?|elementitem(json)?}}<br/>{{Func|json:parse|$string as xs:string?, $options as map(*)?|item()?}}|-| '''Summary'''|Converts the JSON {{Code|$string}} to an XQuery value. If the input can be successfully parsed, it can be serialized back to the original JSON representation. The {{Code|$options}} argument can be used to control the way the input is converted.|-| '''Errors'''|{{Error|parse|#Errors}} the specified input cannot be parsed as JSON document.<br/>{{Error|options|#Errors}} the specified options are conflicting.|} ==json:doc== {{Mark|Introduced with BaseX 9.4:}} {| width='100%'|-| width='120' | '''Signatures'''|{{Func|json:doc|$uri as xs:string|item()?}}<br />{{Func|json:doc|$uri as xs:string, $options as itemmap(*)?|item()?}}<br />
|-
| '''Summary'''
|Converts Fetches the JSON document specified referred to by the given {{Code|$inputuri}} and converts it to an XML document or a map. If the input can be successfully parsed, it can be serialized back to the original JSON representationXQuery value. The {{Code|$options}} argument can be used to control the way the input is converted.
|-
| '''Errors'''
|{{Error|BXJS0001parse|#Errors}} the specified input cannot be parsed as JSON document.<br/>{{Error|options|#Errors}} the specified options are conflicting.
|}
|-
| width='120' | '''Signatures'''
|{{Func|json:serialize|$input as nodeitem()?|xs:string}}<br/>{{Func|json:serialize|$input as nodeitem()?, $options as itemmap(*)?|xs:string}}
|-
| '''Summary'''
|Serializes the node specified by {{Code|$input}} as JSON, and returns using the result as specified {{Code|xs:string$options}} instance. , and returns the result as string:* The node input is expected to conform to the output results that are created by the [[#json:parse|json:parse()]] function. All other * Non-conforming items will be serialized as specified for in the [[XQuery 3.1#JSON Serialization|json output method]] of the official specificationrecommendation.<br />Items Values can also be serialized as JSON if with the standard [[Serialization|Serialization Parameter]] feature of XQuery:* The parameter {{Code|method}} is needs to be set to {{Code|json}}.<br/>The , and* the options presented in this article need to be assigned to the {{Code|$optionsjson}} argument can be used to control the way the input is serializedparameter.
|-
| '''Errors'''
|{{Error|BXJS0002serialize|#Errors}} the specified node cannot be serialized as JSON document.
|}
'''Query:'''
<pre classsyntaxhighlight lang="brush:xquery">
let $database := "database"
for $name in file:list('.', false(), '*.json')
let $json := json:parse($file)
return db:add($database, $json, $name)
</presyntaxhighlight>
'''Example 2: Converts a simple JSON string to XML and back'''
'''Query:'''
<pre classsyntaxhighlight lang="brush:xquery">
json:parse('{}')
</presyntaxhighlight>
'''Result:'''
<pre classsyntaxhighlight lang="brush:xml">
<json type="object"/>
</presyntaxhighlight>
'''Query:'''
<pre classsyntaxhighlight lang="brush:xquery">
(: serialize result as plain text :)
declare option output:method 'text';
json:serialize(<json type="object"/>)
</presyntaxhighlight>
'''Result:'''
<pre classsyntaxhighlight lang="brush:xquery">
{ }
</presyntaxhighlight>
'''Example 3: Converts a JSON string with simple objects and arrays'''
'''Query:'''
<pre classsyntaxhighlight lang="brush:xquery">
json:parse('{
"title": "Talk On Travel Pool",
"generator": "http://www.flickr.com/"
}')
</presyntaxhighlight>
'''Result:'''
<pre classsyntaxhighlight lang="brush:xml">
<json type="object">
<title>Talk On Travel Pool</title>
<generator>http://www.flickr.com/</generator>
</json>
</presyntaxhighlight>
'''Example 4: Converts a JSON string with different data types'''
'''Query:'''
<pre classsyntaxhighlight lang="brush:xquery">
let $options := map { 'merge': true() }
return json:parse('{
]
}', $options)
</presyntaxhighlight>
'''Result:'''
<pre classsyntaxhighlight lang="brush:xml">
<json numbers="age code" arrays="phone" objects="json address value">
<first__name>John</first__name>
</phone>
</json>
</presyntaxhighlight>
==JsonML Format==
'''Example 1: Converts all XML documents in a database to the JsonML format and writes them to disk'''
'''Query:'''
<pre classsyntaxhighlight lang="brush:xquery">
for $doc in collection('json')
let $name := document-uri($doc)
let $json := json:serialize($doc, map { 'format': 'jsonml' })
return file:write($name, $json)
</presyntaxhighlight>
'''Example 2: Converts a simple an XML fragment to the JsonML formatdocument with elements and text'''
'''Query:'''
<pre classsyntaxhighlight lang="brush:xquery">json:serialize(<xml/>, map { 'format': 'jsonml' })</pre> '''Result:'''<pre>["xml"]</pre> '''Example 3: Converts an XML document with elements and text''' '''Query:'''<pre class="brush:xquery">
json:serialize(doc('flickr.xml'), map { 'format': 'jsonml' })
</presyntaxhighlight>
'''flickr.xml:'''
<pre classsyntaxhighlight lang="brush:xml">
<flickr>
<title>Talk On Travel Pool</title>
<generator>http://www.flickr.com/</generator>
</flickr>
</presyntaxhighlight>
'''Result:'''
<presyntaxhighlight lang="json">
["flickr",
["title",
["generator",
"http://www.flickr.com/"]]
</presyntaxhighlight>
'''Example 43: Converts a document with nested elements and attributesto JsonML'''
'''Query:'''
<pre classsyntaxhighlight lang="brush:xquery">
json:serialize(doc('input.xml'), map { 'format': 'jsonml' })
</presyntaxhighlight>
'''input.xml:'''
<pre classsyntaxhighlight lang="brush:xml">
<address id='1'>
<!-- comments will be discarded -->
<phone type='home'>212 555-1234</phone>
</address>
</presyntaxhighlight>
'''Result:'''
<presyntaxhighlight lang="json">
["address", {"id":"1"},
["last_name",
["phone", {"type":"home"},
"212 555-1234"]]
</presyntaxhighlight> ==XQuery Format== '''Example 1: Converts a JSON string to XQuery''' '''Query:'''<syntaxhighlight lang="xquery">let $input := '{ "Title": "Drinks", "Author": [ "Jim Daniels", "Jack Beam" ]}'let $data := json:parse($input, map { 'format': 'xquery' })return map:for-each($data, function($k, $v) { $k || ': ' || string-join($v, ', ')})</syntaxhighlight> '''Result:'''<syntaxhighlight lang="json">Author: Jim Daniels, Jack BeamTitle: Drinks</syntaxhighlight> '''Example 2: Converts XQuery data to JSON''' '''Query:'''<syntaxhighlight lang="xquery">for $item in ( true(), 'ABC', array { 1 to 5 }, map { "Key": "Value" })return json:serialize( $item, map { 'format': 'xquery', 'indent': 'no' })</syntaxhighlight> '''Result:'''<syntaxhighlight lang="json">true"ABC"[1,2,3,4,5]{"Key":"Value"}</syntaxhighlight>
=Errors=
|Description
|-
|{{Code|BXJS0001options}}|The specified options are conflicting.|-|{{Code|parse}}
|The specified input cannot be parsed as JSON document.
|-
|{{Code|BXJS0002serialize}}
|The specified node cannot be serialized as JSON document.
|}
=Changelog=
 
;Version 9.4
* Added: [[#json:doc|json:doc]]
 
; Version 9.1
* Updated: [[#json:parse|json:parse]] can be called with empty sequence.
 
;Version 9.0
* Updated: <code>map</code> format renamed to <code>xquery</code>.
* Updated: error codes updated; errors now use the module namespace
 
;Version 8.4
* Updated: <code>unescape</code> changed to <code>escape</code>.
;Version 8.2
* Added: Conversion format <code>[[#Basic|Basicbasic]] conversion format</code>.
;Version 8.0
The module was introduced with Version 7.0.
 
[[Category:XQuery]]
Bureaucrats, editor, reviewer, Administrators
13,550

edits

Navigation menu