Changes

Jump to navigation Jump to search
4,560 bytes added ,  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 two sets various mappings, all of functions in this module: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.
=JSON Functions=Conversion Formats==
[[#json'''A little advice''':parse|json:parse]] in the Database Creation dialog of the GUI, if you select JSON Parsing and [[#json:serializeswitch to the ''Parsing'' tab, you can see the effects of some of the conversion options. ===Direct=== The {{Code|json:serialize]] facilitate 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. # Names (keys) of objects * Object pairs are represented via elements. The name of a pair is encoded, as described in the [[Conversion Module#Keys|Conversion Module]], and used as elements:element name.## Empty names * Array entries are also represented by a single underscore (via elements, with {{Code|&lt;_&gt;...&lt;/_&gt;}})as element name.* Object and array values are stored in text nodes.## Underscore characters * The types of values are rewritten to two underscores (represented via {{Code|__type}}).attributes:## A character that cannot be represented as NCName character is rewritten to an underscore ** The existing types are ''string'', ''number'', ''boolean'', ''null'', ''object'', and its four-digit Unicode''array''.# ** As most values are strings, the members of arrays have no names''string'' 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|&lt;value/&gt;json}} root node. * Object pairs are represented via {{Code|pair}} elements. The name of a pair is used as element stored in a {{Code|name}} attribute.# JSON * Array entries are represented via {{Code|item}} elements.* Object and array values are represented as stored in text nodes.# * The types of values are represented in via {{Code|type}} attributes:## ** The value existing types are ''string'', ''number'', ''boolean'', ''null'', ''object'' , and ''array'' .** As most values are represented strings, the ''string'' type is by default omitted. ===Basic=== 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]]. ===JsonML=== The {{Code|typejsonml}} attributeformat 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]===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''stringcolumn indicates if an option applies to parsing, serialization, or both operations): {| class="wikitable sortable" width="100%"|- valign="top"! width="140" | Option! width="50%" | Description! Allowed! Default! Direction|- valign="top"| {{Code|format}}| Specifies the format for converting JSON data.| {{Code|direct}}, {{Code|attributes}}, {{Code|jsonml}}, {{Code|xquery}}| {{Code|direct}}| ''parse'', ''serialize''|- valign="top"| {{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'' type |- valign="top"| {{Code|merge}}| This option is omitted, as it considered when {{Code|direct}} or {{Code|attributes}} conversion is treated as default type.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 the plural (''numbers'', ''booleans'', ''nulls'', ''objects'' and ''arrays''), and the attribute value contains all names with that type, separated by whitespaces.| {{Code|yes}}, {{Code|no}}| {{Code|no}}| ''parse'', ''serialize''|- valign="top"| {{Code|strings}}| Indicates if {{Code|type}} attributes will be added for strings.| {{Code|yes}}, {{Code|no}}| {{Code|yes}}| ''parse'', ''serialize''|- valign="top"| {{Code|lax}}| Specifies if a lax approach is used to convert QNames to JSON names.| {{Code|yes}}, {{Code|no}}| {{Code|no}}| ''parse'', ''serialize''|- valign="top"| {{Code|escape}}| 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}}| {{Code|yes}}| ''parse''|- valign="top"| {{Code|escape}}| Indicates if characters are escaped whenever the JSON syntax requires it. This option can be set to {{Code|no}} if strings are already in escaped form and no further escaping is permitted.| {{Code|yes}}, {{Code|no}}| {{Code|yes}}| ''serialize''|- valign="top"| {{Code|indent}}| Indicates if whitespace should be added to the output with the aim of improving human legibility. If the parameter is set as in the query prolog, it overrides the {{Code|indent}} [[Serialization|serialization parameter]].| {{Code|yes}}, {{Code|no}}| {{Code|yes}}| ''serialize''|} =Functions=
==json:parse==
Updated with {| width='100%'|-| width='120' | '''Signatures'''|{{Func|json:parse|$string as xs:string?|item()?}}<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 {{VersionCode|7$options}} argument can be used to control the way the input is converted.7|-| '''Errors'''|{{Error|parse|#Errors}} the specified input cannot be parsed as JSON document.2<br/>{{Error|options|#Errors}}the specified options are conflicting.|==json:doc== {{Mark|Introduced with BaseX 9.4: options added}}
{| width='100%'
|-
| width='120' | '''Signatures'''
|{{Func|json:parsedoc|$input uri as xs:string|elementitem(json)?}}<br/>{{Func|json:parsedoc|$input uri as xs:string, $options as itemmap(*)?|elementitem(json)?}}<br />
|-
| '''Summary'''
|Converts Fetches the JSON document specified referred to by the given {{Code|$inputuri}} 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 converts it to the original JSON representationan XQuery value.<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]):* {{Code|spec}} determines the used JSON specification. Allowed values are RFC4627, ECMA-262, and 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|true}}.Options can either be specified<br />* 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>
|-
| '''Errors'''
|{{Error|BXJS0001parse|#Errors}} the specified input cannot be parsed as JSON document.<br/>{{Error|options|#Errors}} the specified options are conflicting.
|}
==json:serialize==
 
{| width='100%'
|-
| width='120' | '''Signatures'''
|{{Func|json:serialize|$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, and returns using the result as specified {{Code|xs:string$options}} instance. , and returns the result as string:* The serialized node must input is expected to conform to the syntax specified results that are created by the [[#json:parse|json:parse()]] function.<br />XML documents * Non-conforming items will be serialized as specified in the [[XQuery 3.1#JSON Serialization|json output method]] of the official recommendation.Values can also be serialized as JSON if with the standard [[Serialization|Serialization Option]] feature of XQuery:* The parameter {{Code|"method"}} is needs to be set to {{Code|"json"}}, and* the options presented in this article need to be assigned to the {{Code|json}} parameter.
|-
| '''Errors'''
|{{Error|BXJS0002serialize|#Errors}} the specified node cannot be serialized as JSON document.
|}
=Examples= ==ExamplesBaseX Format==
'''Example 1: Adds all JSON documents in a directory to a database'''
'''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 Functions= [[#json:serialize-ml|json:serialize-ml]] and [[#json:parse-ml|json:parse-ml]] are used to transform XML to JSON and back, using the [http://jsonml.org 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 [http://jsonml.org/XML JsonML documentation]. ==json:serialize-ml=={| width='100%'|-| width='120' | '''Signatures'''|{{Func|json:serialize-ml|$input as node()|xs:string}}|-| '''Summary'''|Serializes the node specified by {{Code|$input}} and returns the result as {{Code|xs:string}} instance.<br />XML documents can also be output in the JsonML format by setting the [[Serialization|Serialization Option]] {{Code|"method"}} to {{Code|"jsonml"}}.|-| '''Errors'''|{{Error|BXJS0002|#Errors}} the specified value cannot be serialized.|} ==json:parse-ml=={| width='100%'|-| width='120' | '''Signatures'''|{{Func|json:parse-ml|$input as xs:string|element()}}|-| '''Summary'''|Converts the [http://jsonml.org JsonML] 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.|}
==ExamplesJsonML 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)
</pre> '''Example 2: Converts a simple XML fragment to the JsonML format''' '''Query:'''<pre class="brush:xquery">json:serialize-ml(<xml/>)</presyntaxhighlight>
'''Result:'''<pre>["xml"]</pre> '''Example 32: Converts an XML document with elements and text'''
'''Query:'''
<pre classsyntaxhighlight lang="brush:xquery">json:serialize-ml(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-ml(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|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