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.
===XQuery===
The {{Code|xquery}} 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]]. Before {{Version|9.0}}, it was named {{Code|map}} (it has been renamed because it may also generate strings and other types).
===Basic===
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==
|- valign="top"
| {{Code|format}}
| Specifies the format for converting JSON data([[#Conversion Formats|see above]]).| {{Code|direct}}, {{Code|attributes}}, {{Code|basic}}, {{Code|jsonml}}, {{Code|xquery}}
| {{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}}
|- valign="top"
| {{Code|lax}}
| Specifies if a [[Conversion Module#Keys|lax approach is conversion rules]] are used to convert QNames to JSON names.
| {{Code|yes}}, {{Code|no}}
| {{Code|no}}
| 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|yesno}}
| ''serialize''
|}
=Functions=
==json:doc==
{| width='100%'
|- valign="top"
| width='120' | '''Signature'''
|<pre>json:doc(
$href as xs:string,
$options as map(*)? := map { }
) as item()?</pre>
|- valign="top"
| '''Summary'''
|Fetches the JSON document referred to by the given {{Code|$href}} and converts it to an XQuery value. The {{Code|$options}} argument can be used to control the way the input is converted.
|- valign="top"
| '''Errors'''
|{{Error|parse|#Errors}} the specified input cannot be parsed as JSON document.<br/>{{Error|options|#Errors}} the specified options are conflicting.
|}
==json:parse==
{| width='100%'
|-valign="top"| width='120' | '''SignaturesSignature'''|{{Func|json:parse|$input as xs:string|element(json)}}<br/pre>{{Func|json:parse|( $input value as xs:string?, $options as map(xs*)? :string, xs:string= map { })|as item()}}?</pre>|-valign="top"
| '''Summary'''
|Converts the JSON document specified by {{Code|$inputvalue}} to an XML document or a mapXQuery 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.|-valign="top"
| '''Errors'''
|{{Error|BXJS0001parse|#Errors}} the specified input cannot be parsed as JSON document.<br/>{{Error|options|#Errors}} the specified options are conflicting.
|}
{| width='100%'
|-valign="top"| width='120' | '''SignaturesSignature'''|{{Func|json:serialize|$input as item()?|xs:string}}<br/pre>{{Func|json:serialize|( $input as item()?, $options as map(xs*)? :string, xs:string= map { })|as xs:string}}</pre>|-valign="top"
| '''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{{Function||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.|-valign="top"
| '''Errors'''
|{{Error|BXJS0002serialize|#Errors}} the specified node cannot be serialized as JSON document.
|}
'''Query:'''
<pre classlang="brush:'xquery"'>
let $database := "database"
for $name in file:list('.', false(), '*.json')
'''Query:'''
<pre classlang="brush:'xquery"'>
json:parse('{}')
</pre>
'''Result:'''
<pre classlang="brush:xml">
<json type="object"/>
</pre>
'''Query:'''
<pre classlang="brush:'xquery"'>
(: serialize result as plain text :)
declare option output:method 'text';
'''Result:'''
<pre classlang="brush:'xquery"'>
{ }
</pre>
'''Query:'''
<pre classlang="brush:'xquery"'>
json:parse('{
"title": "Talk On Travel Pool",
'''Result:'''
<pre classlang="brush:xml">
<json type="object">
<title>Talk On Travel Pool</title>
'''Query:'''
<pre classlang="brush:'xquery"'>
let $options := map { 'merge': true() }
return json:parse('{
'''Result:'''
<pre classlang="brush:xml">
<json numbers="age code" arrays="phone" objects="json address value">
<first__name>John</first__name>
'''Query:'''
<pre classlang="brush:'xquery"'>
for $doc in collection('json')
let $name := document-uri($doc)
'''Query:'''
<pre classlang="brush:'xquery"'>
json:serialize(doc('flickr.xml'), map { 'format': 'jsonml' })
</pre>
'''flickr.xml:'''
<pre classlang="brush:xml">
<flickr>
<title>Talk On Travel Pool</title>
'''Result:'''
<prelang="json">
["flickr",
["title",
'''Query:'''
<pre classlang="brush:'xquery"'>
json:serialize(doc('input.xml'), map { 'format': 'jsonml' })
</pre>
'''input.xml:'''
<pre classlang="brush:xml">
<address id='1'>
<!-- comments will be discarded -->
'''Result:'''
<prelang="json">
["address", {"id":"1"},
["last_name",
'''Query:'''
<pre classlang="brush:'xquery"'>
let $input := '{
"Title": "Drinks",
'''Result:'''
<prelang="json">
Author: Jim Daniels, Jack Beam
Title: Drinks
'''Query:'''
<pre classlang="brush:'xquery"'>
for $item in (
true(),
'''Result:'''
<prelang="json">
true
"ABC"
! width="110"|Code
|Description
|-valign="top"|{{Code|BXJS0001options}}|The specified options are conflicting.|- valign="top"|{{Code|parse}}
|The specified input cannot be parsed as JSON document.
|-valign="top"|{{Code|BXJS0002serialize}}
|The specified node cannot be serialized as JSON document.
|}
=Changelog=
;Version 10.0
* Updated: {{Code|indent}}: Default changed from {{Code|yes}} to {{Code|no}}.
;Version 9.4
* Added: {{Function||json:doc}}
; Version 9.1
* Updated: {{Function||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
;Version 7.7.2
* Updated: {{Code|$options}} argument added to [[#json:parse{{Function||json:parse]] }} and [[#json:serialize{{Function||json:serialize]]}}.* Updated: [[#json:parse-ml{{Function||json:parse-ml]] }} and [[#json:serialize-ml{{Function||json:serialize-ml]] }} are now ''deprecated''.
The module was introduced with Version 7.0.