Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the differences between JSONiq and XQuery 3.1?

Both JSONiq and XQuery 3.1 extend XQuery 3.0 with support for JSON.

How do they differ?

like image 545
Ghislain Fourny Avatar asked Jul 05 '17 07:07

Ghislain Fourny


2 Answers

Overall motivation

XQuery 3.1 was designed with the goal to support additional data structures (maps, arrays) in memory. These structures are mapped to JSON for input and output. XQuery 3.1 has been a W3C recommendation since March 2017.

JSONiq was designed with the goal of querying and updating JSON in settings such as document stores. It was also designed by members of the XML Query working group (disclaimer: I am one of them) while investigating various possibilities to support JSON. While it is not an official recommendation, it is stable and public.

Data model

Both XQuery 3.1 and JSONiq extend the data model with objects and arrays, but do so in different ways, motivated by their distinct focuses. Overall, XQuery 3.1 has a more generic data model, while JSONiq restricts it to mirror JSON.

In JSONiq, object keys must be strings. In XQuery 3.1, they can be any atomic value.

In JSONiq, values in objects and arrays must be single items, in particular, arrays are homomorphic to sequences even though they are distinct. In XQuery 3.1, values in object and arrays can be sequences of items.

In JSONiq, nulls are represented with a dedicated atomic type. In XQuery 3.1, they are represented with empty sequences (which are accepted values in the data model).

In XQuery 3.1, values are not copied with populating an array or map, which supports among others building indices on XML nodes. In JSONiq, copies are made similarly to XML constructors, to ensure a strict tree semantics.

Construction

The syntax for constructing objects and arrays in JSONiq is a superset of JSON.

{ "foo" : [ 1 to 10 ] }

In XQuery 3.1, it is similar to computed XML node constructors:

map { "foo" : array { 1 to 10 } }

XQuery 3.1 has an alternate syntax for arrays in which commas delimite the slots for the values, to nest sequences:

[ 1, (1 to 10), 11 ]

Navigation

XQuery 3.1 uses function calls to perform lookups in objects and arrays:

let $map := map { "foo" : "bar" }
return $map("foo")

let $array := array { 1, 2, 3 }
return $array(2)

It also uses ? as a shortcut for unquoted names and integers:

let $map := map { "foo" : "bar" }
return $map?foo

let $array := array { 1, 2, 3 }
return $array?2

let $array := array { 1, 2, 3 }
return $array?*

JSONiq (the core language) uses dots and square brackets

let $map := { "foo" : "bar" }
return $map.foo

let $array := [ 1, 2, 3 ]
return $array[[2]]

let $array := [ 1, 2, 3 ]
return $array[]

(JSONiq also exists as an extension to XQuery that also overloads the function call syntax).

like image 61
Ghislain Fourny Avatar answered Nov 05 '22 01:11

Ghislain Fourny


I am a little disappointed in how XQuery 3.1 supports Json.

One of the basic requirements is to be fully compatible with Json syntax, which just likes XQuery compatible with XML syntax and JSONiq compatible with Json syntax, so that customers can start from existing Json files. A prolog is acceptable, if must explicitly enable Json-compatible syntax.

Unfortunately, in standard XQuery 3.1, you must write map{...} for Json object, true() for Json value true, false() for Json value false, and () for Json value null. Converting Json files into Json templates will be painful.

XQuery 3.1 supports interspersing strings for plain text templates. If converting Json files into plain text templates, you must handle XQuery return values carefully, b/c it does not care about Json data types and escape quoted strings.

Conclusion

JSONiq (when work on Json only) and XQuery with JSONiq extension (when work on both XML and Json) are better solutions for converting Json files into Json templates.

like image 25
Charge AA Avatar answered Nov 05 '22 03:11

Charge AA