Changes

Jump to navigation Jump to search
896 bytes removed ,  13: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|<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|http://basex.org/errors}} namespace, which is statically bound to the {{Code|bxerr}} prefix.
==Conversion Formats==
The '''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 rules have been updated with {{Version|7options.8}}:
===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|_}})encoded, existing underscores are rewritten to two underscores ({{Code|__}}), and characters that are not valid as described in element names are rewritten to an underscore and the character’s four-digit Unicode.[[Conversion Module## If the {{Code|lax}} option is set to {{CodeKeys|false}}Conversion Module]], invalid characters are simply replaced with underscores. The resulting names are better readable, but may not be losslessly converted back to their original formand used as element name.# * Array entries are also represented via elements. , with {{Code|<_>}} is used as element name ({{Code|value}} was used before {{Version|7.8}}).# * 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 is the default, it '' type is by default omitted.
===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 is the default, it '' type is by default omitted.
===MapBasic===
The {{Code|mapbasic}} format is another losslessformat. It converts a JSON document to an XML node and vice versa. The conversion rules for are specified in the same as for [[XSLT XQuery 3.01#fn:json-to-xml|httpfn://www.w3.org/TR/xslt-30/#funcjson-parseto-json specificationxml]].
===JsonML===
The {{Code|jsonml}} format can be used is designed to transform 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]. ===XQuery=== The {{Code|xquery}} format is lossless, too. It converts JSON data to an XQuery value (a map, array, string, number, boolean, or empty sequence) and vice versa. The conversion rules are the same as for [[XQuery 3.1#fn:parse-json|fn:parse-json]]. The resulting representation consumes less memory than XML-based formats, and values can be directly accessed without conversion. Thus, it is recommendable for very large inputs and for efficient ad-hoc processing.
==Options==
The following options are available(the ''Direction'' column indicates if an option applies to parsing, serialization, or both operations):
{| class="wikitable sortable" width="100%"
| {{Code|format}}
| Specifies the format for converting JSON data.
| {{Code|direct}}, {{Code|attributes}}, {{Code|jsonml}}, {{Code|mapxquery}}
| {{Code|direct}}
| ''parse'', ''serialize''
|- valign="top"
| {{Code|spec}}
| Determines the specification that is used for parsing JSON data:<br/>
* {{Code|RFC4627}} allows no deviations from the grammar
* {{Code|ECMA-262}} allows single values as input
* {{Code|liberal}} allows single values and accepts keys without quotes, trailing commas and non-escaped control characters.
| {{Code|RFC4627}}, {{Code|ECMA-262}}, {{Code|liberal}}
| {{Code|liberal}}
| Determines if minor deviations from [https://www.rfc-editor.org/rfc/rfc7159.txt RFC 7159] will be ignored.| {{Code|yes}}, {{Code|no}}| {{Code|no}}| ''parse'', ''serialize''
|- valign="top"
| {{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}}
| Specifies if a lax approach is used to convert QNames to JSON names.
| {{Code|yes}}, {{Code|no}}
| {{Code|yesno}}
| ''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|<csv:options/>}} element; e.g.:
<pre class="brush:xml">
<csv:options>
<csv:separator value=';'/>
...
</csv:options>
</pre>
* or as map, which contains all key/value pairs:
<pre class="brush:xquery">
{ 'separator': ';', ... }
</pre>
=Functions=
==json:parse==
 
{{Version|7.7.2}}: {{Code|$options}} argument added
{| width='100%'
|-
| width='120' | '''Signatures'''
|{{Func|json:parse|$input string as xs:string?|elementitem(json)?}}<br/>{{Func|json:parse|$input string as xs:string?, $options as itemmap(*)?|elementitem(json)?}}
|-
| '''Summary'''
|Converts the JSON document specified by {{Code|$inputstring}} to XML, and returns an XQuery value. If the result as {{Code|element(json)}} instance. The converted XML document is both well readable and lossless, i.e.input can be successfully parsed, the converted document it 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|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'''
|{{Error|BXJS0001parse|#Errors}} the specified input cannot be parsed as JSON document.<br/>{{Error|BXJS0003options|#Errors}} a the specified option cannot be parsedoptions are conflicting.
|}
==json:serializedoc==
{{VersionMark|7Introduced with BaseX 9.7.2}}4: {{Code|$options}} argument added
{| width='100%'
|-
| width='120' | '''Signatures'''
|{{Func|json:serializedoc|$input uri as node()|xs:string|item()?}}<br/>{{Func|json:serializedoc|$input uri as node()xs:string, $options as map(*)?|item()|xs:string?}}<br />
|-
| '''Summary'''
|Serializes Fetches the node specified by {{Code|$input}} as JSON, and returns the result as {{Code|xs:string}} instance. The serialized node must conform document referred 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]] given {{Code|method$uri}} is set and converts it to {{Code|json}}an XQuery value.<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}} and {{Code|jsonml}}; the default is {{Code|json}}converted.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'''
|{{Error|BXJS0002parse|#Errors}} the specified node input cannot be serialized parsed as JSON document.<br/>{{Error|options|#Errors}} the specified options are conflicting.
|}
==json:serialize-ml== {{Version|7.7.2}}: deprecated; please use [[#json:serialize|json:serialize]] instead.
{| width='100%'
|-
| width='120' | '''Signatures'''
|{{Func|json:serialize-ml|$input as nodeitem()?|xs:string}}<br/>{{Func|json:serialize|$input as item()?, $options as map(*)?|xs:string}}
|-
| '''Summary'''
|Serializes the node specified by {{Code|$input}} as JSON, using the specified {{Code|$options}}, and returns the result as {{Codestring:* The input is expected to conform to the results that are created by [[#json:parse|xsjson:string}} instanceparse()]].<br />XML documents can also * Non-conforming items will be output serialized as specified in the JsonML format by setting the [[XQuery 3.1#JSON Serialization|json output method]] of the official recommendation.Values can also be serialized as JSON with the standard [[Serialization Option]] feature of XQuery:* The parameter {{Code|method}} needs to be set to {{Code|json}}, and* the options presented in this article need to be assigned to the {{Code|jsonmljson}}parameter.
|-
| '''Errors'''
|{{Error|BXJS0002serialize|#Errors}} the specified value node cannot be serialized.|} ==json:parse-ml== {{Version|7.7.2}}: deprecated; please use [[#json:parse|json:parse]] instead. {| width='100%'|-| width='120' | '''Signatures'''|{{Func|json:parse-ml|$input as xs:string|element()}}|-| '''Summary'''|Converts the [http://jsonml.org JsonML] JSON document specified by {{Code|$input}} to XML, and returns the result as {{Code|element()}} instance. The JSON input must conform to the JsonML specification to be successfully converted.|-| '''Errors'''|{{Error|BXJS0001|#Errors}} the specified input cannot be parsed as JsonML instance.
|}
'''Query:'''
<pre classsyntaxhighlight lang="brush:xquery">
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) </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 objectstype="jsonobject"/></presyntaxhighlight>
'''Query:'''
<pre classsyntaxhighlight lang="brush:xquery">
(: serialize result as plain text :)
declare option output:method 'text';
json:serialize(<json objectstype="jsonobject"/>)</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",
"link": "http://www.flickr.com/groups/talkontravel/pool/",
"description": "Travel and vacation photos from around the world.",
"modified": "20092014-02-02T11:10:27Z",
"generator": "http://www.flickr.com/"
}')
</presyntaxhighlight>
'''Result:'''
<pre classsyntaxhighlight lang="brush:xml"><json objectstype="jsonobject">
<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>20092014-02-02T11:10:27Z</modified>
<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('{
"first_name": "John",
"last_name": "Smith",
}
]
}', $options)</presyntaxhighlight>
'''Result:'''
<pre classsyntaxhighlight lang="brush:xml">
<json numbers="age code" arrays="phone" objects="json address value">
<first__name>John</first__name>
</address>
<phone>
<value_>
<type>home</type>
<number>212 555-1234</number>
</value_> <value_>
<type>mobile</type>
<number type="number">1327724623</number>
</value_>
</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/>, { '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>
<link>http://www.flickr.com/groups/talkontravel/pool/</link>
<description>Travel and vacation photos from around the world.</description>
<modified>20092014-02-02T11:10:27Z</modified>
<generator>http://www.flickr.com/</generator>
</flickr>
</presyntaxhighlight>
'''Result:'''
<presyntaxhighlight lang="json">
["flickr",
["title",
"Talk On Travel Pool"],
["link",
"http:\/\/www.flickr.com\/groups\/talkontravel\/pool\/"],
["description",
"Travel and vacation photos from around the world."],
["modified",
"20092014-02-02T11:10:27Z"],
["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.
|-
|{{Code|BXJS0003}}
|A specified option cannot be parsed.
|}
=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|basic]]</code>.
 
;Version 8.0
* Updated: Serialization aligned with the {{Code|json}} output method of the official specification.
* Added: {{Code|liberal}} option.
* Removed: {{Code|spec}} option.
 
;Version 7.8
* Removed: {{Code|json:parse-ml}}, {{Code|json:serialize-ml}}.
* Updated: {{Code|json:parse}} now returns a document node instead of an element, or an XQuery map if {{Code|format}} is set to {{Code|.map}}.
;Version 7.7.2
* Updated: {{Code|$options}} argument added to [[#json:parse|json:parse]] and [[#json:serialize|json:serialize]].* Updated: [[#json:parse-ml|json:parse-ml]] and [[#json:serialize-ml|json:serialize-ml]] are now ''deprecated''.
The module was introduced with Version 7.0.
 
[[Category:XQuery]]
Bureaucrats, editor, reviewer, Administrators
13,550

edits

Navigation menu