5.4. Composing Constructors
Of course, JSONiq would not be very interesting if all you could do is copy and paste JSON documents. So now is time to get to the meat.
Because JSONiq expressions are fully composable, in objects and arrays constructors, you can put way more than just atomic literals, object constructors and array constructors: you can put any JSONiq expression. An expression is the JSONiq building block. You already know some (literals, constructors, comma, cast, instance of) and plenty more will be introduced in the next part (arithmetics, logic, comparison, if-then-else, try-catch, FLWORS that allow you to join, select, group, filter, project, stream in windows, ...)
In order to illustrate composability, the following examples use a few of the many operators you can use:
"to" for creating sequences of consecutive integers,
"||" for concatenating strings,
"+" for adding numbers,
"," for appending sequences (yes, you already know this one).
So here we go.
In an array, the operand expression inside the square bracket will evaluated to a sequence of items, and these items will be copied and become members of the newly created array.
Example 5.8. Composable array constructors.
[ 1 to 10 ],
[ "foo" || "bar", 1 to 3, 2 + 2 ]
Results:
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
[ "foobar", 1, 2, 3, 4 ]
In an object, the expression you use for the key must evaluate to an atomic - if it is not a string, it will just get cast to it.
An error is raised if the key expression is not an atomic.
Example 5.9. Composable object keys.
{ "foo" || "bar" : true },
{ 1 + 1 : "foo" }
Results:
{
"foobar" : true
}
{
"2" : "foo"
}
And do not worry about the value expression: if it is empty, null will be used as a value, and if it contains two items or more, they will be wrapped into an array.
Example 5.10. Composable object values.
{ "foo" : 1 + 1 },
{ "foo" : (), "bar" : (1, 2) }
Results:
{
"foo" : 2
}
{
"foo" : null,
"bar" : [ 1, 2 ]
}
The {| |} constructor can be used to merge several objects.
Example 5.11. Merging object constructor.
{| { "foo" : "bar" }, { "bar" : "foo" } |}
Results:
{
"foo" : "bar",
"bar" : "foo"
}
An error is raised if the operand expression does not evaluate to a sequence of objects.