xquery version "1.0";
(:
: Copyright 2006-2012 The FLWOR Foundation.
:
: Licensed under the Apache License, Version 2.0 (the "License");
: you may not use this file except in compliance with the License.
: You may obtain a copy of the License at
:
: http://www.apache.org/licenses/LICENSE-2.0
:
: Unless required by applicable law or agreed to in writing, software
: distributed under the License is distributed on an "AS IS" BASIS,
: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
: See the License for the specific language governing permissions and
: limitations under the License.
:)
(:~
: This module provides the functions defined by the JSONiq specification,
: chapter 8 (Function Library). JSONiq extends
: the XQuery specification to also deal with JSON data natively. See
:
: http://jsoniq.org/
:
: for details.
:
: This module depends on having the JSONiq feature enabled in Zorba,
: i.e., Zorba must be compiled with ZORBA_WITH_JSON.
:
: @author Ghislain Fourny
:)
module namespace libjn = "http://jsoniq.org/function-library";
import module namespace jn = "http://jsoniq.org/functions";
declare namespace ver = "http://www.zorba-xquery.com/options/versioning";
declare option ver:module-version "1.0";
(:~
: This function dynamically builds an object, like jn:object, except that
: it does not throw an error upon pair collision. Instead, it aggregates them
: into an array.
:
: @param $o A sequence of objects.
: @return The accumulated object.
:)
declare function libjn:accumulate($o as object()*) as object()
{
{[ $o ]}
};
(:~
: This function returns all Objects contained within a JSON item, regardless of
: depth.
:
: @param $i A JSON item.
: @return Its descendant objects.
:)
declare function libjn:descendant-objects($i as json-item()) as object()*
{
if ($i instance of object())
then
(
$i,
for $v in libjn:values($i)
where $v instance of json-item()
return libjn:descendant-objects($v)
)
else if ($i instance of array())
then
(
for $v in libjn:members($i)
where $v instance of json-item()
return libjn:descendant-objects($v)
)
else
()
};
(:~
: This function returns all pairs contained within an object, recursively.
:
: @param $o An object.
: @return All direct and indirect descendant pairs.
:)
declare function libjn:descendant-pairs($o as object()) as object()*
{
for $k in jn:keys($o)
return (
{ $k : $o($k) },
if ($o($k) instance of object())
then
libjn:descendant-pairs($o($k))
else ()
)
};
(:~
: Recursively "flatten" a JSON Array, by replacing any arrays with their
: members. Equivalent to
:
: define function jn:flatten($arg as array()) {
: for $value in jn:values($arg)
: return
: if ($value instance of array())
: then jn:flatten($value)
: else $value
: };
:
: @param $a A JSON Array.
: @return The flattened version of $a.
:)
declare function libjn:flatten($a as array()) as item()*
{
jn:flatten($a)
};
(:~ This function returns the intersection of two objects, and aggregates
: values corresponding to the same name into an array.
:
: @param $o A sequence of objects.
: @return Their insersection.
:)
declare function libjn:intersect($o as object()*) as object()
{
{|
let $common-keys := jn:keys($o[1])[ every $object in $o[position() > 1]
satisfies jn:keys($object) = . ]
for $key in $common-keys
let $values := $o($key)
return
if (count($values) eq 1)
then { $key : $values }
else { $key : [ $values ] }
|}
};
(:~
: Returns the members of an Array.
:
: @param $a A JSON Array.
: @return The members of the specified array.
:)
declare function libjn:members($o as array()) as item()*
{
jn:members($o)
};
(:~
: Creates an object from the specified pairs of another given object.
: Specifically, for each name in $names, if the object $o has a pair with
: that name, then a copy of that pair is included in the new object.
:
: @param $o A JSON Object.
: @param $names The names of the pairs to copy out of $o and insert into the new object
: @return The new object.
:)
declare function libjn:project($o as object(), $names as xs:string*) as object()
{
jn:project($o, $names)
};
(:~
: This functions returns all values in an Object.
: @param $i An object.
: @return Its values.
:)
declare function libjn:values($i as object()) as item()*
{
for $k in jn:keys($i)
return $i($k)
};