Changes

Jump to navigation Jump to search
9,918 bytes added ,  13:06, 2 July 2020
This [[Module Library|XQuery Module]] contains functions to parse and serialize JSON data [httphttps://www.json.org/ JSON (JavaScript Object Notation)] is a popular data exchange format for applications written in JavaScript. This module contains [[Querying#Functions|As there are notable differences between JSON and XML, or XQuery functions]] to parse data types, no mapping exists that guarantees a lossless, bidirectional conversion between JSON and serialize JSON documentsXML. All functions are preceded by the <code>json:</code> prefixFor this reason, we offer various mappings, all of which is linked are suited to the <code><nowiki>http://www.basex.org/json</nowiki></code> namespacedifferent use cases.
As there are notable differences between JSON and XML, no mapping exists that guarantees a lossless conversio[[JSON Functions#json:parse|json:parse()]] and [[JSON Functions#json:serialize|json:serialize()]] facilitate a lossless representation of JSON in XML and back, while [[JSON Functions#json:parse-ml|json:parse-ml()]] and [[JSON Functions#json:serialize-ml|json:serialize-ml()]] are used to transform XML to JSON and back.=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/> ==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 encoded, as described in the [[Conversion Module#Keys|Conversion Module]], and used as element name.* Array entries are also represented via elements, with {{Code|_}} as element name.* 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. ===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 proposed 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. ===Basic=== The {{Code|basic}} format is another lossless format. It converts a JSON functions 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|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]. ===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 with <font color(the ''Direction'' column 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="redtop">Version 6| {{Code|liberal}}| Determines if minor deviations from [https://www.rfc-editor.org/rfc/rfc7159.7txt RFC 7159] will be ignored.2| {{Code|yes}}, {{Code|no}}| {{Code|no}}| ''parse''|- valign="top"| {{Code|merge}}| This option is considered when {{Code|direct}} or {{Code|attributes}} conversion is used:<br/font> or <font color* If a name has the same type throughout the data, 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}}| {{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="redtop">6| {{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.8</font> | {{Code|yes}}, {{Code|no}}| {{Code|yes}}| ''serialize''|- valign="top"| {{Code|indent}}| Indicates if whitespace should be added to the output with the aim of BaseXimproving 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==
 {|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 {{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%'
|-
| valign='top' width='90120' | '''Signatures'''|<code><b>{{Func|json:parsedoc|$uri as xs:string|item()?}}<br /b>({{Func|json:doc|$input uri as xs:string, $options as map(*)) as element?|item(json)?}}<br /code>
|-
| valign='top' | '''Summary'''|Converts Fetches the JSON document specified referred to by <code>the given {{Code|$input</code> uri}} and converts it to XML, and returns the result as <code>element(json)</code> instancean XQuery value. The converted XML document is both well readable and lossless, i.e., the converted document {{Code|$options}} argument can be serialized back used to control the original JSON representation. The transformation is based on way the following rules:# The resulting document has a <code><json/></code> root node. # Names (keys) of objects are represented as elements:## Empty names are represented by a single underscore (<code>&lt;_&gt;...&lt;/_&gt;</code>).## Underscore characters are rewritten to two underscores (<code>__</code>).## A character that cannot be represented as NCName character input is rewritten to an underscore and its four-digit Unicode.# As arrays have no names, {@code <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 <code>type</code> attribute.## The ''string'' type is omitted, as it is treated as default type.## If a name has the same type throughout the document, the <code>type</code> 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 whitespacesconverted.
|-
| valign='top' | '''Errors'''|<b>[[XQuery Errors{{Error|parse|#BaseX Errors (BASX)|BASX0015]]</b> is raised if }} the specified input cannot be parsed as JSON document.<br/>{{Error|options|#Errors}} the specified options are conflicting.
|}
==json:serialize==
 {|width='100%'
|-
| valign='top' width='90120' | '''Signatures'''|<code><b>{{Func|json:serialize|$input as item()?|xs:string}}<br/b>({{Func|json:serialize|$input as nodeitem()?, $options as map(*) as ?|xs:string()</code>}}
|-
| valign='top' | '''Summary'''|Serializes the node specified by <code>{{Code|$input</code> }} as JSON, using the specified {{Code|$options}}, and returns the result as <code>xsstring:string</code> instance. * The serialized node must input is expected to conform to the syntax specified results that are created by the [[JSON Functions#json:parse|json:parse()]] function.<br />XML documents * Non-conforming items will be serialized as specified in the [[XQuery 3.1#JSON format Serialization|json output method]] of the official recommendation.Values can also be serialized if as JSON with the standard [[Serialization|Serialization Option]] <code>"feature of XQuery:* The parameter {{Code|method"</code> is }} needs to be set to <code>"{{Code|json}}, and* the options presented in this article need to be assigned to the {{Code|json"</code>}} parameter.
|-
| valign='top' | '''Errors'''|<b>[[XQuery Errors{{Error|serialize|#BaseX Errors (BASX)|BASX0016]]</b> is raised if }} the specified node cannot be serialized as JSON document.
|}
=Examples= ==BaseX Format== '''Example 1: Adds all JSON documents in a directory to a database''' '''Query:'''<syntaxhighlight lang="xquery">let $database :=Examples"database"for $name in file:list('.', false(), '*.json')let $file :=file:read-text($name)let $json :=json:parse($file)return db:add($database, $json, $name) </syntaxhighlight>
'''Example 12: A basic example Converts a simple JSON string to convert an empty JSON documentXML and back'''
'''Query:'''
<pre classsyntaxhighlight lang="brush:xquery">
json:parse('{}')
</presyntaxhighlight>
'''Result:'''
<pre classsyntaxhighlight lang="brush:xml"><jsontype="object"/></presyntaxhighlight>
'''Query:'''<syntaxhighlight lang="xquery">(: serialize result as plain text :)declare option output:method 'text';json:serialize(<json type="object"/>)</syntaxhighlight> '''Result:'''<syntaxhighlight lang="xquery">{ }</syntaxhighlight> '''Example 23: Conversion of some 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"><jsontype="object">
<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 34: Globally defined Converts a JSON string with different data types, key rewritings'''
'''Query:'''
<pre classsyntaxhighlight lang="brush:xquery">let $options := map { 'merge': true() }return json:parse('{ "first_name": "John", "last_name": "John Smith",
"age": 25,
"address": {
"type": "home",
"number": "212 555-1234"
},
{
"type": "mobile",
"number": 1327724623
}
]
}', $options)</presyntaxhighlight>
'''Result:'''
<pre classsyntaxhighlight lang="brush:xml">
<json numbers="age code" arrays="phone" objects="json address value">
<first__name>John</first__name> <last__name>John Smith</last__name>
<age>25</age>
<address>
</address>
<phone>
<value_>
<type>home</type>
<number>212 555-1234</number>
</value_> <_> <type>mobile</type> <number type="number">1327724623</number> </_>
</phone>
</json>
</presyntaxhighlight==JsonML Format== '''Example 1: Converts all XML documents in a database to the JsonML format and writes them to disk''' '''Query:'''<syntaxhighlight lang="xquery">for $doc in collection('json')let $name := document-uri($doc)let $json := json:serialize($doc, map { 'format': 'jsonml' })return file:write($name, $json)</syntaxhighlight> '''Example 2: Converts an XML document with elements and text''' '''Query:'''<syntaxhighlight lang="xquery">json:serialize(doc('flickr.xml'), map { 'format': 'jsonml' })</syntaxhighlight> '''flickr.xml:'''<syntaxhighlight lang="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>2014-02-02T11:10:27Z</modified> <generator>http://www.flickr.com/</generator></flickr></syntaxhighlight> '''Result:'''<syntaxhighlight 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", "2014-02-02T11:10:27Z"], ["generator", "http://www.flickr.com/"]]</syntaxhighlight> '''Example 3: Converts a document with nested elements and attributes to JsonML''' '''Query:'''<syntaxhighlight lang="xquery">json:serialize(doc('input.xml'), map { 'format': 'jsonml' })</syntaxhighlight> '''input.xml:'''<syntaxhighlight lang="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></syntaxhighlight> '''Result:'''<syntaxhighlight lang="json">["address", {"id":"1"}, ["last_name", "Smith"], ["age", "25"], ["address", ["street", "21 2nd Street"], ["city", "New York"], ["code", "10021"]], ["phone", {"type":"home"}, "212 555-1234"]]</syntaxhighlight> ==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= {| class="wikitable" width="100%"! width="110"|Code|Description|-|{{Code|options}}|The specified options are conflicting.|-|{{Code|parse}}|The specified input cannot be parsed as JSON document.|-|{{Code|serialize}}|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.
Bureaucrats, editor, reviewer, Administrators
13,550

edits

Navigation menu