The Zorba collection functions

1 Introduction

This document defines the functions that will perform manipulations on collections in the Zorba engine.

1.1 Collections in Zorba

Each collection is defined to be a sequence of nodes that is one based indexed, identified by an URI.
The collections concern themselves only with the top-level sequence of nodes, and do not have any functions to manipulate the nodes or their contents.
A node may be part of more than one collection, still the node is unique within every collection.
When added to a collection, a node is not copied, and further modifications to it will be reflected in the collection.

1.2 Namespaces

In order to use Zorba collection functionality, the module "http://www.zorba-xquery.com/zorba/collection-functions" has to be included at the beginning of a query. For example

  import module namespace zorba-collection = "http://www.zorba-xquery.com/zorba/collection-functions";

2 Function Signatures and Descriptions

Most of the collection functions will be sequential functions (marked by "sequential" keyword).

2.1 fn:collection

  declare function collection()                   as node()*
  declare function collection($uri as xs:anyURI)  as node()*

This is provided here for completeness. It will return the nodes from the collection identified by the given URI.

For details about this function please see chapter 15.5.6 fn:collection from XQuery 1.0 and XPath 2.0 Functions and Operators

2.2 zorba-collection:import-xml

  declare function import-xml($uri as xs:anyURI) as none

Summary: This function will import a given XML document, identified by the $uri parameter, into a new collection.
The collection's URI will be the value of the $uri parameter.
If the $uri is found in the collection poll no import is done.

Error conditions:
If the XML file specified by the $uri parameter does not exist, an error is raised API0033_FILE_OR_FOLDER_DOES_NOT_EXIST (see Appendix A: Error codes).
If the XML file cannot be opened, an error is raised API0034_FILE_OR_FOLDER_CANNOT_BE_OPENED (see Appendix A: Error codes).

2.3 zorba-collection:import-catalog

  declare function import-catalog($uri as xs:anyURI) as none

Summary: The function will open the given XML file and interpret it as a catalog.
Assuming $uri is 'file://localhost/home/user_1/catalog.xml', it must have the following structure:

<catalog>
  <doc href="file1.xml"/>
  <doc href="path/file2.xml"/>
  <doc href="path/file3.xml"/>
  ...
</catalog>

Each of the documents referenced in the <doc> tags is first looked up in the collection poll.
If it is already present, nothing is done, otherwise it is loaded as a collection, with the href attribute value as the associated URI.
The URIs of the catalog and the files may include a protocol specification, such as "file://" or "http://".
The function will not validate the catalog file's structure. In case it is malformed - no XML files will be imported.

In case a href attribute contains no path, only the name of the file (see the first href attribute in the example above) the file will be looked in the same path as the catalog ('file://localhost/home/user_1/file1.xml' in the example above).

Error conditions:
If the catalog file specified by the $uri parameter or any of the files specified by the href attributes does not exist, an error is raised API0033_FILE_OR_FOLDER_DOES_NOT_EXIST (see Appendix A: Error codes).
If the catalog file or the href files cannot be opened, an error is raised API0034_FILE_OR_FOLDER_CANNOT_BE_OPENED (see Appendix A: Error codes).

2.4 zorba-collection:list-collections

  declare function list-collections() as xs:anyURI*

Summary: The function will return a sequence of URIs of all currently know collections.

Example:

import module namespace
fn-zorba-collection="http://www.zorba-xquery.com/zorba/collection-functions";
fn-zorba-collection:list-collections()

2.5 zorba-collection:create-collection

  declare sequential function create-collection($uri    as xs:anyURI,
                                                $nodes  as node()*  ) as none

Summary: The first function will create a new, empty, collection.
The second function will create a new collection and will add the given nodes to it.

Error conditions:
If the collection already exists, an error is raised API0005_COLLECTION_ALREADY_EXISTS (see Appendix A: Error codes).

Example:

import module namespace
fn-zorba-collection="http://www.zorba-xquery.com/zorba/collection-functions";

declare sequential function local:foo() {
  fn-zorba-collection:create-collection('http://example.org/collection_1', (<a/>,<b/>));
  exit with ();
};

local:foo()

2.6 zorba-collection:delete-collection

  declare sequential function delete-collection()                   as none
  declare sequential function delete-collection($uri as xs:string?) as none

Summary: The function will delete the collection identified by the given URI.

Error conditions:

If the collection does not exist, an error is raised: API0006_COLLECTION_NOT_FOUND (see Appendix A: Error codes). If the collection URI is empty and the default collection is not defined in the dynamic context, FODC0002 is raised (see Appendix A: Error codes).

Example:

declare base-uri "http://example.org/";
import module namespace
fn-zorba-collection="http://www.zorba-xquery.com/zorba/collection-functions";

declare sequential function local:foo() {
  fn-zorba-collection:delete-collection('collection_333');
  exit with ();
};

local:foo()

2.7 zorba-collection:delete-all-collections

  declare sequential function delete-all-collections() as none

Summary: The function will delete all existing collections.

2.8 zorba-collection:insert-nodes-first

  declare sequential function insert-nodes-first( $newnode  as node()*    ) as none
  declare sequential function insert-nodes-first( $uri      as xs:string?,
                                                  $newnode  as node()*    ) as none

Summary: The function will insert copies of the given node(s) as the first node(s) of the given collection.
If multiple nodes are inserted, the nodes remain adjacent and their order preserves the node ordering of the source expression.

Error conditions:
If the specified collection does not exist, an error is raised API0006_COLLECTION_NOT_FOUND (see Appendix A: Error codes).
If the node is already in the collection, an error is raised API0031_NODE_ALREADY_IN_COLLECTION (see Appendix A: Error codes).
If the collection URI is empty and the default collection is not defined in the dynamic context, FODC0002 is raised (see Appendix A: Error codes).

Example:

import module namespace coll="http://www.zorba-xquery.com/zorba/collection-functions";

declare sequential function local:create() {
  coll:create-collection("test");
  exit with coll:collection-exists("test");
};

declare sequential function local:insert() {
  coll:insert-nodes-first("test", for $i in 1 to 10 return <a> { $i } </a>);
  exit with fn:collection("test");
};

if (fn:not(local:create())) then
  fn:false()
else 
  local:insert()

2.9 zorba-collection:insert-nodes-last

  declare sequential function insert-nodes-last($newnode  as node()*    ) as none
  declare sequential function insert-nodes-last($uri      as xs:string?,
                                                $newnode  as node()*    ) as none

Summary: The function will insert copies of the given node(s) as the last node(s) of the given collection.
If multiple nodes are inserted, the nodes remain adjacent and their order preserves the node ordering of the source expression.

Error conditions:
If the specified collection does not exist, an error is raised API0006_COLLECTION_NOT_FOUND (see Appendix A: Error codes).
If the node is already in the collection, an error is raised API0031_NODE_ALREADY_IN_COLLECTION (see Appendix A: Error codes).
If the collection URI is empty and the default collection is not defined in the dynamic context, FODC0002 is raised (see Appendix A: Error codes).

Example:

import module namespace coll="http://www.zorba-xquery.com/zorba/collection-functions";

declare sequential function local:create() {
  coll:create-collection("test");
  coll:insert-nodes-first("test", for $i in 1 to 10 return <a> { $i } </a>);
  exit with (fn:count(fn:collection("test")) eq 10);
};

declare sequential function local:insert() {
  coll:insert-nodes-last("test", for $i in 11 to 13 return <b> { $i } </b>);
  exit with fn:collection("test");
};

if (fn:not(local:create())) then
  fn:false()
else 
  local:insert()

2.10 zorba-collection:insert-nodes-before

  declare sequential function insert-nodes-before($target   as node()+,
                                                  $newnode  as node()*    ) as none
  declare sequential function insert-nodes-before($uri      as xs:string?,
                                                  $target   as node()+,
                                                  $newnode  as node()*    ) as none

Summary: The inserted nodes become the preceding nodes of the $target.
The $target should be a non-updating expression (e.g. an XPath expression) identifying a node that is part of the given collection at the top-level.
If the expression returns more than one node, the first one is used. A predicate can be used to select a different node in this case.
If multiple nodes are inserted by a single insert expression, the nodes remain adjacent and their order preserves the node ordering of the source expression.

Error conditions:
If the specified collection does not exist, an error is raised API0006_COLLECTION_NOT_FOUND (see Appendix A: Error codes).
If the given expression points to node that is not part of the collection, an error is raised API0029_NODE_DOES_NOT_BELONG_TO_COLLECTION (see Appendix A: Error codes).
If $target is already part of the collection an error is raised API0031_NODE_ALREADY_IN_COLLECTION (see Appendix A: Error codes).
If the collection URI is empty and the default collection is not defined in the dynamic context, FODC0002 is raised (see Appendix A: Error codes).

Example:

import module namespace coll="http://www.zorba-xquery.com/zorba/collection-functions";

declare sequential function local:test()
{
  coll:create-collection("a");
  coll:insert-nodes-first("a", (<a/>, <b/>, <c/>));
  coll:insert-nodes-before("a", fn:collection("a")[2], <z/>);
  exit with fn:collection("a");
};

local:test()

2.11 zorba-collection:insert-nodes-after

  declare sequential function insert-nodes-after( $target   as node()+,
                                                  $newnode  as node()*    ) as none
  declare sequential function insert-nodes-after( $uri      as xs:string?,
                                                  $target   as node()+,
                                                  $newnode  as node()*    ) as none

Summary: The inserted nodes become the following nodes of the $target.
The $target should be a non-updating expression (e.g. an XPath expression) identifying a node that is part of the given collection at the top-level.
If the expression returns more than one node, the first one is used. A predicate can be used to select a different node in this case.
If multiple nodes are inserted by a single insert expression, the nodes remain adjacent and their order preserves the node ordering of the source expression.

Error conditions:
If the specified collection does not exist, an error is raised API0006_COLLECTION_NOT_FOUND (see Appendix A: Error codes).
If the given expression points to node that is not part of the collection, an error is raised API0029_NODE_DOES_NOT_BELONG_TO_COLLECTION (see Appendix A: Error codes).
If $target is already part of the collection an error is raised API0031_NODE_ALREADY_IN_COLLECTION (see Appendix A: Error codes).
If the collection URI is empty and the default collection is not defined in the dynamic context, FODC0002 is raised (see Appendix A: Error codes).

Example:

import module namespace coll="http://www.zorba-xquery.com/zorba/collection-functions";

declare sequential function local:test()
{
  coll:create-collection("a");
  coll:insert-nodes-last("a", <a/>);
  coll:insert-nodes-last("a", <b/>);
  coll:insert-nodes-last("a", <c/>);
  coll:insert-nodes-after("a", fn:collection("a")[2], <z/>);
  exit with fn:collection("a");
};

local:test()

2.12 zorba-collection:insert-nodes-at

  declare sequential function insert-nodes-at($position as xs:integer,
                                              $newnode  as node()*    ) as none
  declare sequential function insert-nodes-at($uri      as xs:string?,
                                              $position as xs:integer,
                                              $newnode  as node()*    ) as none

Summary: Inserts copies of the node(s) into the given collection, at the specified $position.
Note: The collection is a list of nodes that is one based indexed.
If $position is negative, the node(s) will be inserted at the beginning of the collection.
If $position is greater or equal to the number of nodes in the collection, the node(s) will be inserted as the last node(s) of the collection.

Error conditions:
If the specified collection does not exist, an error is raised API0006_COLLECTION_NOT_FOUND (see Appendix A: Error codes).
If the node is already part of the collection an error is raised API0031_NODE_ALREADY_IN_COLLECTION (see Appendix A: Error codes).
If the collection URI is empty and the default collection is not defined in the dynamic context, FODC0002 is raised (see Appendix A: Error codes).

Example:

import module namespace coll="http://www.zorba-xquery.com/zorba/collection-functions";

declare sequential function local:test()
{
  coll:create-collection("a");
  coll:insert-nodes-last("a", <a/>);
  coll:insert-nodes-last("a", <b/>);
  coll:insert-nodes-last("a", <c/>);
  coll:insert-nodes-at("a", 2, <z/>);
  exit with fn:collection("a");
};

local:test()

2.13 zorba-collection:remove-nodes

  declare sequential function remove-nodes( $target as node()+    ) as none
  declare sequential function remove-nodes( $uri    as xs:string?,
                                            $target as node()+    ) as none

Summary: The function will remove the node(s) identified by the $target expression from the given collection.
The nodes themselves will not be deleted and they may remain as parts of other collections.
If the expression identifies more than one node, all of them will be removed from the collection. A predicate can be used to select a single node, if needed.

Error conditions:
If the specified collection does not exist, an error is raised API0006_COLLECTION_NOT_FOUND (see Appendix A: Error codes).
If the given expression points to a node that is not part of the collection, an error is raised API0029_NODE_DOES_NOT_BELONG_TO_COLLECTION (see Appendix A: Error codes).
If the collection URI is empty and the default collection is not defined in the dynamic context, FODC0002 is raised (see Appendix A: Error codes).

Example:

import module namespace coll="http://www.zorba-xquery.com/zorba/collection-functions";

declare sequential function local:test()
{
  coll:create-collection("a");
  coll:insert-nodes-last("a", <a/>);
  coll:insert-nodes-last("a", <b/>);
  coll:insert-nodes-last("a", <c/>);
  coll:remove-nodes("a", fn:collection("a")[position()<3]);
  exit with fn:collection("a");
};

local:test()

2.14 zorba-collection:remove-node-at

  declare sequential function remove-node-at( $position as xs:integer ) as none
  declare sequential function remove-node-at( $uri      as xs:string?,
                                              $position as xs:integer ) as none

Summary: The function will remove from the given collection the node positioned at $position.
Note: The collection is a list of nodes that is one based indexed.

Error conditions:
If the specified collection does not exist, an error is raised API0006_COLLECTION_NOT_FOUND (see Appendix A: Error codes).
If the collection has fewer nodes than $position + 1, nothing is removed and an error is raised API0030_NO_NODE_AT_GIVEN_POSITION (see Appendix A: Error codes).
If the collection URI is empty and the default collection is not defined in the dynamic context, FODC0002 is raised (see Appendix A: Error codes).

Example:

import module namespace coll="http://www.zorba-xquery.com/zorba/collection-functions";

declare sequential function local:test()
{
  coll:create-collection("a");
  coll:insert-nodes-last("a", <a/>);
  coll:insert-nodes-last("a", <b/>);
  coll:insert-nodes-last("a", <c/>);
  coll:remove-node-at("a", 2);
  exit with fn:collection("a");
};

local:test()

2.15 zorba-collection:nodes-count

  declare sequential function nodes-count()                   as xs:integer?
  declare sequential function nodes-count($uri as xs:string?) as xs:integer?

Summary: The function returns the number of nodes in the given collection.

Error conditions:
If the specified collection does not exist, an error is raised API0006_COLLECTION_NOT_FOUND (see Appendix A: Error codes).
If the collection URI is empty and the default collection is not defined in the dynamic context, FODC0002 is raised (see Appendix A: Error codes).

Example:

import module namespace
fn-zorba-collection="http://www.zorba-xquery.com/zorba/collection-functions";
fn-zorba-collection:nodes-count('http://example.org/collection_333')

2.16 zorba-collection:node-at

  declare sequential function node-at($position as xs:integer ) as node()?
  declare sequential function node-at($uri      as xs:string?,
                                      $position as xs:integer ) as node()?

Summary: The function will return the node positioned at $position in the given collection.
Note: The collection is a list of nodes that is one based indexed.

Error conditions:
If the specified collection does not exist, an error is raised API0006_COLLECTION_NOT_FOUND (see Appendix A: Error codes).
If the collection has fewer nodes than $position + 1 an error is raised API0030_NO_NODE_AT_GIVEN_POSITION (see Appendix A: Error codes).
If the collection URI is empty and the default collection is not defined in the dynamic context, FODC0002 is raised (see Appendix A: Error codes).

Example:

import module namespace coll="http://www.zorba-xquery.com/zorba/collection-functions";

declare sequential function local:test()
{
  coll:create-collection("a");
  coll:insert-nodes-last("a", <a/>);
  coll:insert-nodes-last("a", <b/>);
  coll:insert-nodes-last("a", <c/>);
  exit with coll:node-at("a",2);
};

local:test()

2.17 zorba-collection:index-of

  declare function index-of($target as node()     ) as xs:integer
  declare function index-of($uri    as xs:string?,
                            $target as node()     ) as xs:integer

Summary: The function will return the index of the $target node within the collection identified by $uri.
Note: The collection is a list of nodes that is one based indexed.

Error conditions:
If the specified collection does not exist, an error is raised API0006_COLLECTION_NOT_FOUND (see Appendix A: Error codes).
If the node does not belong to the given collection, an error is raised API0029_NODE_DOES_NOT_BELONG_TO_COLLECTION (see Appendix A: Error codes).
If the collection URI is empty and the default collection is not defined in the dynamic context, FODC0002 is raised (see Appendix A: Error codes).

Example:

import module namespace coll="http://www.zorba-xquery.com/zorba/collection-functions";

declare sequential function local:test()
{
  coll:create-collection("a");
  coll:insert-nodes-last("a", <a/>);
  coll:insert-nodes-last("a", <b/>);
  coll:insert-nodes-last("a", <c/>);
  exit with coll:index-of("a",fn:collection("a")[2]);
};

local:test()

2.18 zorba-collection:export-xml

  declare updating function export-xml( $uri        as xs:string ) as none
  declare updating function export-xml( $uri        as xs:string,
                                        $targeturi  as xs:string ) as none

Summary: Saves the given collection to the target URI as an XML file.
Intended supported targets (protocols) are:
"file:///path/file.xml" : (e.g. "file://c:/path/folder/file.xml") - saves the collection to a file, in the serialized form.
"http://www.example.com/path/file.xml" - saves the collection to a remote location, via the HTTP PUT request (to be implemented by the REST library).
If the protocol is omitted in the URI, "file://" is assumed.
The first function will use the collection's URI (the $uri parameter) as the target URI.
The collection will be exported only if it can be serialized correctly - i.e. it is a well-formed XML document.

Error conditions:
If the collection can not be serialized correctly an error will be returned API0035_COLLECTION_CANNOT_BE_SERIALIZED (see Appendix A: Error codes).

2.19 zorba-collection:collection-exists

  declare function collection-exists()                    as xs:boolean
  declare function collection-exists( $uri as xs:string?) as xs:boolean

Summary: Returns true is a collection with the requested $uri is found in the collection poll, false otherwise.
If the collection URI is empty and the default collection is not defined in the dynamic context, FODC0002 is raised (see Appendix A: Error codes).

Appendix A: Error codes

API0006_COLLECTION_NOT_FOUND - collection does not exist.
API0005_COLLECTION_ALREADY_EXISTS - collection already exists.
API0029_NODE_DOES_NOT_BELONG_TO_COLLECTION - the node does not belong to the given collection.
API0030_NO_NODE_AT_GIVEN_POSITION - there is no node at the given position, the collection has fewer nodes.
API0031_NODE_ALREADY_IN_COLLECTION - the node is already part of the collection.
API0033_FILE_OR_FOLDER_DOES_NOT_EXIST - the file or folder does not exist.
API0034_FILE_OR_FOLDER_CANNOT_BE_OPENED - a file or folder cannot be opened.
API0035_COLLECTION_CANNOT_BE_SERIALIZED - the collection cannot be serialized.
FODC0002 - Default collection undefined in the dynamic context.