Change module version declaration back to "xquery".

xquery version "1.0";
(:
 : Copyright 2006-2013 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 a function (np:node-position) that, given a node,
 : returns positional information about the node in the form of an xs:anyURI
 : item. The module also defines functions that use such positional information
 : to determine: (1) positional relationships between two nodes (e.g. if one
 : is the ancestor of another) and (2) positional properties of a single node
 : (e.g. its level in the tree).

 :

 :
Within this module, the term "node position" will be used to refer to an
 : xs:anyURI item that is returned by the np:node-position function.

 :
 : @author Federico Cavalieri, Markos Zaharioudakis
 :
 : @project Zorba/XQuery Data Model/Node/Node Position
 :)
module namespace np = "http://zorba.io/modules/node-position";

declare namespace ver = "http://www.zorba-xquery.com/options/versioning";
declare option ver:module-version "2.0";

(:~
 :
Return a URI item containing positional information for a given node.

 :

 :
Within a snapshot, each has a different positional URI. However,
 : different nodes in different snapshots might have the same URI.

 :
 : @param $arg the node for which the positional information URI
 :  should be computed
 :
 : @return the opaque positional information URI of the node.
 :)
declare function np:node-position(
  $arg as node()
) as xs:anyURI external;

(:~
 :
Determines whether the node position given as second argument is
 : an ancestor of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is an ancestor of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential descendant node position
 : @param $n-pos2 the potential ancestor node position
 :
 : @return true if the node position $n-pos2 is an ancestor of the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:ancestor-of(
  $pos1 as xs:anyURI,
  $pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : a descendant of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a descendant of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential ancestor node position
 : @param $n-pos2 the potential descendant node position
 :
 : @return true if the node position $n-pos2 is a descendant of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:descendant-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument belongs
 : to the subtree rooted at the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node belongs to the subtree rooted at the
 : first. Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.

 :

 :
This function differs from np:descendant-of in the way it treats attribute
 : nodes. np:descendant-of follows the XQuery/XPath specification for the
 : descendant axis, and as a result, it does not consider attributes as
 : descendants of any nodes; it will always return false if $n-pos2 was
 : obtained from an attribute node.In contrast, np:in-subtree-of will return
 : true if $n-pos2 was obtained from an attribute node that appeared in the
 : subtree of the node that $n-pos1 was obtained from.

 :
 : @param $n-pos1 the potential subtree root node position
 : @param $n-pos2 the potential node in the subtree node position
 :
 : @return true if the node position $n-pos2 belongs to the subtree rooted at
 : the node position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-subtree-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : the parent of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is the parent of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential child node position
 : @param $n-pos2 the potential parent node position
 :
 : @return true if the node position $n-pos2 is the parent of the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:parent-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : a child of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a child of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential parent node position
 : @param $n-pos2 the potential child node position
 :
 : @return true if the node position $n-pos2 is a child of the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:child-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : an attribute of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is an attribute of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential parent node position
 : @param $n-pos2 the potential attribute node position
 :
 : @return true if the node position $n-pos2 is an attribute of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:attribute-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : a following-sibling of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a following-sibling of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential preceding-sibling node position
 : @param $n-pos2 the potential following-sibling node position
 :
 : @return true if the node position $n-pos2 is a following-sibling of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:following-sibling-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : a preceding-sibling of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a preceding-sibling of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential following-sibling node position
 : @param $n-pos2 the potential preceding-sibling node position
 :
 : @return true if the node position $n-pos2 is a preceding-sibling of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:preceding-sibling-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether two node positions are siblings.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a sibling of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 a node position
 : @param $n-pos2 a node position
 :
 : @return true if the two node positions $n-pos1 and $n-pos2 are siblings;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:sibling-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : following the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is following the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential preceding node position
 : @param $n-pos2 the potential following node position
 :
 : @return true if node positions $n-pos1 and $n-pos2 belong to the same XML
 :         tree and $n-pos2 is following the node position $n-pos1; false
 :         otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node position
 :        computed by the <tt>np:node-position</tt> function.
 :)
declare function np:following-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : following in document order the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is following in document order the
 : first.

 :
Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential preceding node position
 : @param $n-pos2 the potential following node position
 :
 : @return true if the node position $n-pos2 is following in document order the
 : node position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:following-in-document-order-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : preceding the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is preceding the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential following node position
 : @param $n-pos2 the potential preceding node position
 :
 : @return true if node positions $n-pos1 and $n-pos2 belong to the same XML
 :         tree and $n-pos2 is preceding the node position $n-pos1; false
 :         otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:preceding-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : preceding in document order the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is preceding in document order the
 : first.

 :
Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential following node position
 : @param $n-pos2 the potential preceding node position
 :
 : @return true if the node position $n-pos2 is preceding in document order the
 : node position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:preceding-in-document-order-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Computes the level of a node position in its tree.

 :

 :
Note: The root node of a tree is at level one.

 :

 :
The result of the function applies to the corresponding node as well,
 : that is, within the snapshot in which the position was computed, the node
 : level is the returned one.

 :
The result of the function does not imply anything about the
 : node level in other snapshots.

 :
 : @param $n-pos the node position of the node whose level should be
 : determined.
 :
 : @return the level in the tree of the node position $n-pos as xs:integer.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:level(
  $n-pos as xs:anyURI) as xs:integer external;

(:~
 :
Determines whether a node position corresponds to an attribute node.

 :
 : @param $n-pos the potential attribute node position
 :
 : @return true if the node position $n-pos corresponds to an attribute;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-attribute(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether a node position corresponds to a comment node.

 :
 : @param $n-pos the potential comment node position
 :
 : @return true if the node position $n-pos corresponds to an comment;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-comment(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether a node position corresponds to a document node.

 :
 : @param $n-pos the potential document node position
 :
 : @return true if the node position $n-pos corresponds to a document;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-document(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether a node position corresponds to an element node.

 :
 : @param $n-pos the potential element node position
 :
 : @return true if the node position $n-pos corresponds to an element;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-element(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether a node position corresponds to an processing-instruction
 : node.

 :
 : @param $n-pos the potential processing-instruction node position
 :
 : @return true if the node position $n-pos corresponds to a processing
 : instruction; false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-processing-instruction(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether a node position corresponds to a text node.

 :
 : @param $n-pos the potential text node position
 :
 : @return true if the node position $n-pos corresponds to a text;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-text(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether two node positions belong to the same tree.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the two nodes belong to the same tree.

 :
Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.

 :
 : @param $n-pos1 a node position
 : @param $n-pos2 a node position
 :
 : @return true if the two nodes whose node positions are $n-pos1
 : and $n-pos2 belong to the same tree.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-same-tree-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether a node position belongs to a collection.

 :
 : @param $n-pos the node position
 :
 : @return true if the node position $n-pos
 : belongs to a collection; false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-collection(
  $n-pos as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether two node positions belong to the same collection.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the two nodes belong to the same collection.

 :
Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.

 :
 : @param $n-pos1 a node position
 : @param $n-pos2 a node position
 :
 : @return true if the two nodes whose node positions are $n-pos1
 : and $n-pos2 belong to the same collection.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-same-collection-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

jsoniq version "1.0";
(:
 : Copyright 2006-2011 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 a function (np:node-position) that, given a node,
 : returns positional information about the node in the form of an xs:anyURI
 : item. The module also defines functions that use such positional information
 : to determine: (1) positional relationships between two nodes (e.g. if one
 : is the ancestor of another) and (2) positional properties of a single node
 : (e.g. its level in the tree).

 :

 :
Within this module, the term "node position" will be used to refer to an
 : xs:anyURI item that is returned by the np:node-position function.

 :
 : @author Federico Cavalieri, Markos Zaharioudakis
 :
 : @project Zorba/XQuery Data Model/Node/Node Position
 :)
module namespace np = "http://zorba.io/modules/node-position";

declare namespace ver = "http://www.zorba-xquery.com/options/versioning";
declare option ver:module-version "2.0";

(:~
 :
Return a URI item containing positional information for a given node.

 :

 :
Within a snapshot, each has a different positional URI. However,
 : different nodes in different snapshots might have the same URI.

 :
 : @param $arg the node for which the positional information URI
 :  should be computed
 :
 : @return the opaque positional information URI of the node.
 :)
declare function np:node-position(
  $arg as node()
) as xs:anyURI external;

(:~
 :
Determines whether the node position given as second argument is
 : an ancestor of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is an ancestor of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential descendant node position
 : @param $n-pos2 the potential ancestor node position
 :
 : @return true if the node position $n-pos2 is an ancestor of the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:ancestor-of(
  $pos1 as xs:anyURI,
  $pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : a descendant of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a descendant of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential ancestor node position
 : @param $n-pos2 the potential descendant node position
 :
 : @return true if the node position $n-pos2 is a descendant of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:descendant-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument belongs
 : to the subtree rooted at the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node belongs to the subtree rooted at the
 : first. Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.

 :

 :
This function differs from np:descendant-of in the way it treats attribute
 : nodes. np:descendant-of follows the XQuery/XPath specification for the
 : descendant axis, and as a result, it does not consider attributes as
 : descendants of any nodes; it will always return false if $n-pos2 was
 : obtained from an attribute node.In contrast, np:in-subtree-of will return
 : true if $n-pos2 was obtained from an attribute node that appeared in the
 : subtree of the node that $n-pos1 was obtained from.

 :
 : @param $n-pos1 the potential subtree root node position
 : @param $n-pos2 the potential node in the subtree node position
 :
 : @return true if the node position $n-pos2 belongs to the subtree rooted at
 : the node position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-subtree-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : the parent of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is the parent of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential child node position
 : @param $n-pos2 the potential parent node position
 :
 : @return true if the node position $n-pos2 is the parent of the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:parent-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : a child of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a child of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential parent node position
 : @param $n-pos2 the potential child node position
 :
 : @return true if the node position $n-pos2 is a child of the node position
 : $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:child-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : an attribute of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is an attribute of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential parent node position
 : @param $n-pos2 the potential attribute node position
 :
 : @return true if the node position $n-pos2 is an attribute of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:attribute-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : a following-sibling of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a following-sibling of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential preceding-sibling node position
 : @param $n-pos2 the potential following-sibling node position
 :
 : @return true if the node position $n-pos2 is a following-sibling of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:following-sibling-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : a preceding-sibling of the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a preceding-sibling of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential following-sibling node position
 : @param $n-pos2 the potential preceding-sibling node position
 :
 : @return true if the node position $n-pos2 is a preceding-sibling of the node
 : position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:preceding-sibling-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether two node positions are siblings.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is a sibling of the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 a node position
 : @param $n-pos2 a node position
 :
 : @return true if the two node positions $n-pos1 and $n-pos2 are siblings;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:sibling-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : following the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is following the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential preceding node position
 : @param $n-pos2 the potential following node position
 :
 : @return true if node positions $n-pos1 and $n-pos2 belong to the same XML
 :         tree and $n-pos2 is following the node position $n-pos1; false
 :         otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node position
 :        computed by the <tt>np:node-position</tt> function.
 :)
declare function np:following-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : following in document order the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is following in document order the
 : first.

 :
Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential preceding node position
 : @param $n-pos2 the potential following node position
 :
 : @return true if the node position $n-pos2 is following in document order the
 : node position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:following-in-document-order-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : preceding the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is preceding the first.

 :
Otherwise, the result of the function does not imply anything about the
 : positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential following node position
 : @param $n-pos2 the potential preceding node position
 :
 : @return true if node positions $n-pos1 and $n-pos2 belong to the same XML
 :         tree and $n-pos2 is preceding the node position $n-pos1; false
 :         otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:preceding-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether the node position given as second argument is
 : preceding in document order the node position given as first argument.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the second node is preceding in document order the
 : first.

 :
Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.

 :
 : @param $n-pos1 the potential following node position
 : @param $n-pos2 the potential preceding node position
 :
 : @return true if the node position $n-pos2 is preceding in document order the
 : node position $n-pos1; false otherwise.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:preceding-in-document-order-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Computes the level of a node position in its tree.

 :

 :
Note: The root node of a tree is at level one.

 :

 :
The result of the function applies to the corresponding node as well,
 : that is, within the snapshot in which the position was computed, the node
 : level is the returned one.

 :
The result of the function does not imply anything about the
 : node level in other snapshots.

 :
 : @param $n-pos the node position of the node whose level should be
 : determined.
 :
 : @return the level in the tree of the node position $n-pos as xs:integer.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:level(
  $n-pos as xs:anyURI) as xs:integer external;

(:~
 :
Determines whether a node position corresponds to an attribute node.

 :
 : @param $n-pos the potential attribute node position
 :
 : @return true if the node position $n-pos corresponds to an attribute;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-attribute(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether a node position corresponds to a comment node.

 :
 : @param $n-pos the potential comment node position
 :
 : @return true if the node position $n-pos corresponds to an comment;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-comment(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether a node position corresponds to a document node.

 :
 : @param $n-pos the potential document node position
 :
 : @return true if the node position $n-pos corresponds to a document;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-document(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether a node position corresponds to an element node.

 :
 : @param $n-pos the potential element node position
 :
 : @return true if the node position $n-pos corresponds to an element;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-element(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether a node position corresponds to an processing-instruction
 : node.

 :
 : @param $n-pos the potential processing-instruction node position
 :
 : @return true if the node position $n-pos corresponds to a processing
 : instruction; false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-processing-instruction(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether a node position corresponds to a text node.

 :
 : @param $n-pos the potential text node position
 :
 : @return true if the node position $n-pos corresponds to a text;
 : false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:is-text(
  $n-pos1 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether two node positions belong to the same tree.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the two nodes belong to the same tree.

 :
Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.

 :
 : @param $n-pos1 a node position
 : @param $n-pos2 a node position
 :
 : @return true if the two nodes whose node positions are $n-pos1
 : and $n-pos2 belong to the same tree.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-same-tree-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether a node position belongs to a collection.

 :
 : @param $n-pos the node position
 :
 : @return true if the node position $n-pos
 : belongs to a collection; false otherwise.
 :
 : @error zerr:ZAPI0028 if the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-collection(
  $n-pos as xs:anyURI) as xs:boolean external;

(:~
 :
Determines whether two node positions belong to the same collection.

 :

 :
If the two positions were obtained within the same snapshot S, then the
 : result of the function applies to the corresponding nodes as well, that
 : is, within snapshot S, the two nodes belong to the same collection.

 :
Otherwise, the result of the function does not imply anything about
 : the positional relationship of the two nodes.

 :
 : @param $n-pos1 a node position
 : @param $n-pos2 a node position
 :
 : @return true if the two nodes whose node positions are $n-pos1
 : and $n-pos2 belong to the same collection.
 :
 : @error zerr:ZAPI0028 if one of the given URI is not a valid node
 : position computed by the <tt>np:node-position</tt> function.
 :)
declare function np:in-same-collection-of(
  $n-pos1 as xs:anyURI,
  $n-pos2 as xs:anyURI) as xs:boolean external;


[bugfix] Removed redundant serialize-item-separator test

(:
 : eXist-db Open Source Native XML Database
 : Copyright (C) 2001 The eXist-db Authors
 :
 : info@exist-db.org
 : http://www.exist-db.org
 :
 : This library is free software; you can redistribute it and/or
 : modify it under the terms of the GNU Lesser General Public
 : License as published by the Free Software Foundation; either
 : version 2.1 of the License, or (at your option) any later version.
 :
 : This library is distributed in the hope that it will be useful,
 : but WITHOUT ANY WARRANTY; without even the implied warranty of
 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 : Lesser General Public License for more details.
 :
 : You should have received a copy of the GNU Lesser General Public
 : License along with this library; if not, write to the Free Software
 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 :)
xquery version "3.1";

module namespace ser="http://exist-db.org/xquery/test/serialize";

declare namespace test="http://exist-db.org/xquery/xqsuite";

declare %private function ser:adaptive($data, $itemSep as xs:string?) {
    let $options :=
        <output:serialization-parameters
            xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
            <output:method value="adaptive"/>
            <output:indent>no</output:indent>
            {
                if ($itemSep) then
                    <output:item-separator>{$itemSep}</output:item-separator>
                else
                    ()
            }
        </output:serialization-parameters>
    return
        fn:serialize($data, $options)
};

declare %private function ser:adaptive-map-params($data, $itemSep as xs:string?) {
    let $options :=
        map {
            "method": "adaptive",
            "indent": false(),
            "item-separator": $itemSep
        }
    return
        fn:serialize($data, $options)
};

declare %private function ser:adaptive($data) {
    ser:adaptive($data, ())
};

declare %private function ser:adaptive-map-params($data) {
    ser:adaptive-map-params($data, ())
};

declare %private function ser:serialize-with-item-separator($data as item()*, $method as xs:string) {
    let $options :=
        <output:serialization-parameters
            xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
            <output:method value="{$method}"/>
            <output:indent>no</output:indent>
            <output:item-separator>--</output:item-separator>
        </output:serialization-parameters>
    return
        fn:serialize($data, $options)
};

declare variable $ser:atomic :=
    <atomic:root xmlns:atomic="http://www.w3.org/XQueryTest" xmlns:foo="http://www.example.com/foo"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <atomic:duration>P1Y2M3DT10H30M</atomic:duration>
      <atomic:dateTime>2002-04-02T12:00:00Z</atomic:dateTime>
      <atomic:time>13:20:10.5Z</atomic:time>
      <atomic:date>2000-01-01+05:00</atomic:date>
      <atomic:gYearMonth>2001-12</atomic:gYearMonth>
      <atomic:gYear>2001</atomic:gYear>
      <atomic:gMonthDay>--12-17</atomic:gMonthDay>
      <atomic:gDay>---17</atomic:gDay>
      <atomic:gMonth>--12</atomic:gMonth>
      <atomic:boolean>true</atomic:boolean>
      <atomic:base64Binary>R0lGODlhcgGSALMAAAQCAEMmCZtuMFQxDS8b</atomic:base64Binary>
      <atomic:hexBinary>A9FD64E12C</atomic:hexBinary>
      <atomic:float>1267.43233E12</atomic:float>
      <atomic:double>1267.43233E12</atomic:double>
      <atomic:anyURI>http://www.example.com</atomic:anyURI>
      <atomic:NCName atomic:attr="aNCname">aNCname</atomic:NCName>
      <atomic:QName atomic:attr="foo:aQname">foo:aQname</atomic:QName>
      <atomic:string>A String Function</atomic:string>
      <atomic:normalizedString>aNormalizedString</atomic:normalizedString>
      <atomic:language>EN</atomic:language>
      <atomic:decimal atomic:attr="12678967.543233">12678967.543233</atomic:decimal>
      <atomic:integer>12678967543233</atomic:integer>
      <atomic:nonPositiveInteger>-1</atomic:nonPositiveInteger>
      <atomic:long>12678967543233</atomic:long>
      <atomic:nonNegativeInteger>12678967543233</atomic:nonNegativeInteger>
      <atomic:negativeInteger>-12678967543233</atomic:negativeInteger>
      <atomic:int>126789675</atomic:int>
      <atomic:unsignedLong>12678967543233</atomic:unsignedLong>
      <atomic:positiveInteger>12678967543233</atomic:positiveInteger>
      <atomic:short>12678</atomic:short>
      <atomic:unsignedInt>1267896754</atomic:unsignedInt>
      <atomic:byte>126</atomic:byte>
      <atomic:unsignedShort>12678</atomic:unsignedShort>
      <atomic:unsignedByte>126</atomic:unsignedByte>
      <atomic:id1>id1</atomic:id1>
      <atomic:id2>id2</atomic:id2>
      <atomic:idrefs atomic:attr="id1 id2">id1 id2</atomic:idrefs>
    </atomic:root>;

declare variable $ser:test-xsl := document {
    <?xml-stylesheet href="xmldb:exist:///db/serialization-test/test.xsl" type="text/xsl"?>,
    <elem a="abc">123</elem>
};

declare variable $ser:xsl := document {
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
    <xsl:template match="b">processed</xsl:template>
    </xsl:stylesheet>
};

declare variable $ser:test-xml := document {
    <?pi?>,
    <elem a="abc">123</elem>
};

declare variable $ser:collection-name := "serialization-test";

declare variable $ser:collection := "/db/" || $ser:collection-name;

declare
    %test:setUp
function ser:setup() {
    xmldb:create-collection("/db", $ser:collection-name),
    xmldb:store($ser:collection, "test.xml", $ser:test-xml),
    xmldb:store($ser:collection, "test-xsl.xml", $ser:test-xsl),
    xmldb:store($ser:collection, "test.xsl", $ser:xsl)
};

declare
    %test:tearDown
function ser:teardown() {
    xmldb:remove($ser:collection)
};

declare
    %test:assertXPath("contains($result,'atomic')")
function ser:serialize-element() {
    fn:serialize($ser:atomic)
};

declare
    %test:assertError
function ser:serialize-attribute() {
    fn:serialize(($ser:atomic//@*)[1])
};

declare
    %test:assertXPath("contains($result,'atomic')")
function ser:serialize-with-params() {
    let $params :=
      <output:serialization-parameters
           xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
        <output:method value="xml"/>
        <output:indent value="yes"/>
      </output:serialization-parameters>
    return fn:serialize($ser:atomic, $params)
};

declare
    %test:assertXPath("contains($result,'atomic')")
function ser:serialize-with-params-map-params() {
    let $params :=
      map {
        "method": "xml",
        "indent": true()
      }
    return fn:serialize($ser:atomic, $params)
};

declare
    %test:assertXPath("contains($result,'atomic')")
function ser:serialize-no-method() {
    let $params :=
        <output:serialization-parameters xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
            <output:indent value="yes"/>
        </output:serialization-parameters>
    return fn:serialize($ser:atomic, $params)
};

declare
    %test:assertXPath("contains($result,'atomic')")
function ser:serialize-no-method-map-params() {
    let $params :=
        map {
            "indent": true()
        }
    return fn:serialize($ser:atomic, $params)
};

declare
    %test:assertXPath("contains($result,'atomic')")
function ser:serialize-empty-params() {
    let $params := ()
    return fn:serialize($ser:atomic, $params)
};

declare
    %test:assertEquals("aaa
bbb")
function ser:serialize-atomic() {
    let $nodes := ("aaa", "bbb")
    return
        fn:serialize($nodes)
};

declare
    %test:assertEquals("")
function ser:serialize-empty-sequence() {
    let $nodes := ()
    return
        fn:serialize($nodes)
};

declare
    %test:args(1234)
    %test:assertEquals('"1234"')
    %test:args('Hello "world"!')
    %test:assertEquals('"Hello ""world""!"')
function ser:adaptive-simple-atomic($atomic as xs:anyAtomicType) {
    ser:adaptive($atomic)
};

declare
    %test:args(1234)
    %test:assertEquals('"1234"')
    %test:args('Hello "world"!')
    %test:assertEquals('"Hello ""world""!"')
function ser:adaptive-simple-atomic-map-params($atomic as xs:anyAtomicType) {
    ser:adaptive-map-params($atomic)
};

declare
    %test:assertEquals("fn:substring#3
math:pi#0
fn:exists#1
(anonymous-function)#1
Q{http://exist-db.org/xquery/test/serialize}adaptive-simple-atomic#1")
function ser:adaptive-function-item() {
    let $input := (
        substring#3,
        math:pi#0,
        Q{http://www.w3.org/2005/xpath-functions}exists#1,
        function ($a) { $a },
        ser:adaptive-simple-atomic#1
    )
    return
        ser:adaptive($input)
};

declare
    %test:assertEquals("fn:substring#3
math:pi#0
fn:exists#1
(anonymous-function)#1
Q{http://exist-db.org/xquery/test/serialize}adaptive-simple-atomic#1")
function ser:adaptive-function-item-map-params() {
    let $input := (
        substring#3,
        math:pi#0,
        Q{http://www.w3.org/2005/xpath-functions}exists#1,
        function ($a) { $a },
        ser:adaptive-simple-atomic#1
    )
    return
        ser:adaptive-map-params($input)
};

declare
    %test:assertEquals('<?pi?><elem a="abc">123</elem>
<elem a="abc">123</elem>
a="abc"
')
function ser:adaptive-xml() {
    let $input := ($ser:test-xml, $ser:test-xml/elem, $ser:test-xml/elem/@a, $ser:test-xml/elem/comment())
    return
        ser:adaptive($input)
};

declare
    %test:assertEquals('<?pi?><elem a="abc">123</elem>
<elem a="abc">123</elem>
a="abc"
')
function ser:adaptive-xml-map-params() {
    let $input := ($ser:test-xml, $ser:test-xml/elem, $ser:test-xml/elem/@a, $ser:test-xml/elem/comment())
    return
        ser:adaptive-map-params($input)
};

declare
    %test:assertEquals('<?pi?><elem a="abc">123</elem>
<elem a="abc">123</elem>
a="abc"
')
function ser:adaptive-xml-stored() {
    let $doc := doc($ser:collection || "/test.xml")
    let $input := ($doc, $doc/elem, $doc/elem/@a, $doc/elem/comment())
    return
        ser:adaptive($input)
};

declare
    %test:assertEquals('<?pi?><elem a="abc">123</elem>
<elem a="abc">123</elem>
a="abc"
')
function ser:adaptive-xml-stored-map-params() {
    let $doc := doc($ser:collection || "/test.xml")
    let $input := ($doc, $doc/elem, $doc/elem/@a, $doc/elem/comment())
    return
        ser:adaptive-map-params($input)
};

declare
    %test:assertEquals('xmlns:foo="http://exist-db.org/foo"')
function ser:adaptive-xml-namespace() {
    let $input := namespace foo { "http://exist-db.org/foo" }
    return
        ser:adaptive($input)
};

declare
    %test:assertEquals('xmlns:foo="http://exist-db.org/foo"')
function ser:adaptive-xml-namespace-map-params() {
    let $input := namespace foo { "http://exist-db.org/foo" }
    return
        ser:adaptive-map-params($input)
};

declare
    %test:assertEquals("Q{http://exist.sourceforge.net/NS/exist}test")
function ser:adaptive-qname() {
    ser:adaptive(xs:QName("exist:test"))
};

declare
    %test:assertEquals("Q{http://exist.sourceforge.net/NS/exist}test")
function ser:adaptive-qname-map-params() {
    ser:adaptive-map-params(xs:QName("exist:test"))
};

declare
    %test:assertEquals('[(1,2,3),"hello ""world""!",true(),false()]')
function ser:adaptive-array() {
    let $input := [(1 to 3), 'hello "world"!', true(), 1 = 0]
    return
        ser:adaptive($input)
};

declare
    %test:assertEquals('[(1,2,3),"hello ""world""!",true(),false()]')
function ser:adaptive-array-map-params() {
    let $input := [(1 to 3), 'hello "world"!', true(), 1 = 0]
    return
        ser:adaptive-map-params($input)
};

declare
    %test:assertEquals('map{"k1":(1,2,3),"k2":map{"k3":a="abc","k4":[1,2]}}')
function ser:adaptive-map() {
    let $input := map {
        "k1": 1 to 3,
        "k2": map { "k3": $ser:test-xml/elem/@a, "k4": array { 1 to 2 } }
    }
    return
        ser:adaptive($input)
};

declare
    %test:assertEquals('map{"k1":(1,2,3),"k2":map{"k3":a="abc","k4":[1,2]}}')
function ser:adaptive-map-map-params() {
    let $input := map {
        "k1": 1 to 3,
        "k2": map { "k3": $ser:test-xml/elem/@a, "k4": array { 1 to 2 } }
    }
    return
        ser:adaptive-map-params($input)
};

declare
    %test:assertEquals('1.0e0
3.141592653589793e0
2.543e1')
function ser:adaptive-double() {
    let $input := (xs:double(1), xs:double(math:pi()), xs:double(2.543e1))
    return
        ser:adaptive($input)
};

declare
    %test:assertEquals('1.0e0
3.141592653589793e0
2.543e1')
function ser:adaptive-double-map-params() {
    let $input := (xs:double(1), xs:double(math:pi()), xs:double(2.543e1))
    return
        ser:adaptive-map-params($input)
};

declare
    %test:assertEquals('a="abc"
["a",2,<b>123</b>,()]
3.141592653589793e0
math:pi#0
"hello"
"""quoted"""
true()
map{"k":()}')
function ser:adaptive-mixed() {
    let $input := (
        $ser:test-xml/elem/@a,
        ["a", 2, $ser:test-xml/elem/b, ()],
        xs:double(math:pi()),
        math:pi#0,
        "hello",
        '"quoted"',
        2 = 1+1,
        map:entry("k", ())
    )
    return
        ser:adaptive($input)
};

declare
    %test:assertEquals('a="abc"
["a",2,<b>123</b>,()]
3.141592653589793e0
math:pi#0
"hello"
"""quoted"""
true()
map{"k":()}')
function ser:adaptive-mixed-map-params() {
    let $input := (
        $ser:test-xml/elem/@a,
        ["a", 2, $ser:test-xml/elem/b, ()],
        xs:double(math:pi()),
        math:pi#0,
        "hello",
        '"quoted"',
        2 = 1+1,
        map:entry("k", ())
    )
    return
        ser:adaptive-map-params($input)
};

declare
    %test:assertEquals("[]")
function ser:adaptive-empty-array() {
    ser:adaptive([])
};

declare
    %test:assertEquals("[]")
function ser:adaptive-empty-array-map-params() {
    ser:adaptive-map-params([])
};

declare
    %test:assertEquals("map{}")
function ser:adaptive-empty-map() {
    ser:adaptive(map { })
};

declare
    %test:assertEquals("map{}")
function ser:adaptive-empty-map-map-params() {
    ser:adaptive-map-params(map { })
};

declare
    %test:assertEquals("")
function ser:adaptive-empty-seq() {
    ser:adaptive(())
};

declare
    %test:assertEquals("")
function ser:adaptive-empty-seq-map-params() {
    ser:adaptive-map-params(())
};

declare
    %test:assertEquals("content")
function ser:adaptive-text-node() {
    ser:adaptive(<test>content</test>/text())
};

declare
    %test:assertEquals("content")
function ser:adaptive-text-node-map-params() {
    ser:adaptive-map-params(<test>content</test>/text())
};

declare
    %test:assertEquals("")
function ser:adaptive-comment-node() {
    ser:adaptive()
};

declare
    %test:assertEquals("")
function ser:adaptive-comment-node-map-params() {
    ser:adaptive-map-params()
};

declare
    %test:assertEquals("<?target instruction ?>")
function ser:adaptive-processing-instr() {
    ser:adaptive(<?target instruction ?>)
};

declare
    %test:assertEquals("<?target instruction ?>")
function ser:adaptive-processing-instr-map-params() {
    ser:adaptive-map-params(<?target instruction ?>)
};

declare
    %test:assertEquals('att-name="att-value"')
function ser:adaptive-attribute-node() {
    ser:adaptive(attribute att-name { "att-value" })
};

declare
    %test:assertEquals('att-name="att-value"')
function ser:adaptive-attribute-node-map-params() {
    ser:adaptive-map-params(attribute att-name { "att-value" })
};

declare
    %test:assertEquals('[xs:float("NaN")]')
function ser:adaptive-array-with-NaN() {
    ser:adaptive([ xs:float("NaN") ])
};

declare
    %test:assertEquals('[xs:float("NaN")]')
function ser:adaptive-array-with-NaN-map-params() {
    ser:adaptive-map-params([ xs:float("NaN") ])
};

declare
    %test:assertEquals('1-2-3-4-5')
function ser:adaptive-seq-with-item-separator() {
    ser:adaptive(1 to 5, "-")
};

declare
    %test:assertEquals('1-2-3-4-5')
function ser:adaptive-seq-with-item-separator-map-params() {
    ser:adaptive-map-params(1 to 5, "-")
};

declare
    %test:assertEquals('"the quick", "brown fox"')
function ser:adaptive-seq-with-item-separator2() {
    ser:adaptive(("the quick", "brown fox"), ", ")
};

declare
    %test:assertEquals('"the quick", "brown fox"')
function ser:adaptive-seq-with-item-separator2-map-params() {
    ser:adaptive-map-params(("the quick", "brown fox"), ", ")
};

declare
    %test:assertEquals('map{"a":("quotes ("")","apos (')")}')
function ser:adaptive-map-with-itemsep-no-quotes() {
    let $input := map{ "a":("quotes ("")", "apos (')") }
    return
        ser:adaptive($input, ",")
};

declare
    %test:assertEquals('map{"a":("quotes ("")","apos (')")}')
function ser:adaptive-map-with-itemsep-no-quotes-map-params() {
    let $input := map{ "a":("quotes ("")", "apos (')") }
    return
        ser:adaptive-map-params($input, ",")
};

declare
    %test:assertEquals('xs:dateTime("1999-05-31T13:20:00-05:00")')
function ser:adaptive-xs-date-time() {
    ser:adaptive(xs:dateTime('1999-05-31T13:20:00-05:00'))
};

declare
    %test:assertEquals('xs:dateTime("1999-05-31T13:20:00-05:00")')
function ser:adaptive-xs-date-time-map-params() {
    ser:adaptive-map-params(xs:dateTime('1999-05-31T13:20:00-05:00'))
};

declare
    %test:assertEquals('xs:duration("P1Y2M3DT10H30M23S")')
function ser:adaptive-xs-duration() {
    ser:adaptive(xs:duration("P1Y2M3DT10H30M23S"))
};

declare
    %test:assertEquals('xs:duration("P1Y2M3DT10H30M23S")')
function ser:adaptive-xs-duration-map-params() {
    ser:adaptive-map-params(xs:duration("P1Y2M3DT10H30M23S"))
};

declare
    %test:assertEquals('xs:float("1")')
function ser:adaptive-xs-float() {
    ser:adaptive(xs:float("1e0"))
};

declare
    %test:assertEquals('xs:float("1")')
function ser:adaptive-xs-float-map-params() {
    ser:adaptive-map-params(xs:float("1e0"))
};

declare
    %test:assertEquals('1.0e0')
function ser:adaptive-xs-double() {
    let $input := xs:double(1e0)
    return
        ser:adaptive($input, ",")
};

declare
    %test:assertEquals('1.0e0')
function ser:adaptive-xs-double-map-params() {
    let $input := xs:double(1e0)
    return
        ser:adaptive-map-params($input, ",")
};

declare
    %test:assertEquals('1.2,1,0,-1,0,0')
function ser:adaptive-xs-integers() {
    let $input := (xs:decimal(1.2), xs:integer(1), xs:nonPositiveInteger("0"),
        xs:negativeInteger(-1), xs:long(0), xs:int(0))
    return
        ser:adaptive($input, ",")
};

declare
    %test:assertEquals('1.2,1,0,-1,0,0')
function ser:adaptive-xs-integers-map-params() {
    let $input := (xs:decimal(1.2), xs:integer(1), xs:nonPositiveInteger("0"),
        xs:negativeInteger(-1), xs:long(0), xs:int(0))
    return
        ser:adaptive-map-params($input, ",")
};

declare
    %test:assertEquals('"""","""",""""')
function ser:adaptive-string-escaping() {
    let $input := ('"', xs:untypedAtomic('"'), xs:anyURI('"'))
    return
        ser:adaptive($input, ",")
};

declare
    %test:assertEquals('"""","""",""""')
function ser:adaptive-string-escaping-map-params() {
    let $input := ('"', xs:untypedAtomic('"'), xs:anyURI('"'))
    return
        ser:adaptive-map-params($input, ",")
};

declare
    %test:assertEquals('"en","en","en","en","en"')
function ser:adaptive-xs-strings() {
    let $input := (xs:normalizedString("en"), xs:token("en"), xs:language("en"), xs:ID("en"), xs:NCName("en"))
    return
        ser:adaptive($input, ",")
};

declare
    %test:assertEquals('"en","en","en","en","en"')
function ser:adaptive-xs-strings-map-params() {
    let $input := (xs:normalizedString("en"), xs:token("en"), xs:language("en"), xs:ID("en"), xs:NCName("en"))
    return
        ser:adaptive-map-params($input, ",")
};

declare
    %test:assertXPath("contains($result, 'include')")
function ser:exist-expand-xinclude-false() {
    let $doc := document{

                            <title>My Title</title>
                            <xi:include href="{$ser:collection}/test.xml"/>

}
    return
        fn:serialize($doc, map { xs:QName("exist:expand-xincludes"): false() })
};

declare
    %test:assertXPath("contains($result, 'comment')")
function ser:exist-expand-xinclude-true() {
    let $doc := document{

                            <title>My Title</title>
                            <xi:include href="{$ser:collection}/test.xml"/>

}
    return
        fn:serialize($doc, map {  xs:QName("exist:expand-xincludes"): true() })
};

declare
    %test:assertXPath("contains($result, 'true')")
function ser:exist-add-exist-id-all() {
    let $doc := doc($ser:collection || "/test.xml")
    return fn:serialize($doc, map { xs:QName("exist:add-exist-id"): "all" }) eq '<?pi?><elem xmlns:exist="http://exist.sourceforge.net/NS/exist" exist:id="2" exist:source="test.xml" a="abc">123</elem>'
};

declare
    %test:assertXPath("contains($result, 'true')")
function ser:exist-add-exist-id-element() {
    let $doc := doc($ser:collection || "/test.xml")
    return fn:serialize($doc, map { xs:QName("exist:add-exist-id"): "element" })  eq '<?pi?><elem xmlns:exist="http://exist.sourceforge.net/NS/exist" exist:id="2" exist:source="test.xml" a="abc">123</elem>'
};

declare
     %test:assertXPath("not(contains($result, 'exist:id'))")
function ser:exist-add-exist-id-none() {
    let $doc := doc($ser:collection || "/test.xml")
    return fn:serialize($doc, map { xs:QName("exist:add-exist-id"): "none" })
};

declare
    %test:assertXPath("contains($result, 'true')")
function ser:exist-jsonp() {
      let $node := <book>
          <author>John Doe</author>
          <author>Robert Smith</author>
      </book>
    return fn:serialize($node, map {"method":"json", "media-type":"application/json", xs:QName("exist:jsonp"):"functionName"}) eq 'functionName({"author":["John Doe","Robert Smith"]})'
};

declare
    %test:assertEquals('processed')
function ser:exist-process-xsl-pi-true() {
    let $doc := doc($ser:collection || "/test-xsl.xml")
    return fn:serialize($doc, map {xs:QName("exist:process-xsl-pi"): true()})
};

declare
    %test:assertXPath("contains($result, 'stylesheet')")
function ser:exist-process-xsl-pi-false() {
    let $doc := doc($ser:collection || "/test-xsl.xml")
    return fn:serialize($doc, map {xs:QName("exist:process-xsl-pi"): false()})
};

declare
    %test:assertEquals("1--2")
function ser:item-separator-text-method() {
    let $data := (1, 2)
    return ser:serialize-with-item-separator($data, "text")
};

declare
    %test:assertEquals("1--2")
function ser:item-separator-html-method() {
    let $data := (1, 2)
    return ser:serialize-with-item-separator($data, "html")
};

declare
    %test:assertEquals("1--2")
function ser:item-separator-xhtml-method() {
    let $data := (1, 2)
    return ser:serialize-with-item-separator($data, "xhtml")
};

declare
    %test:assertEquals("1--2")
function ser:item-separator-xml-method() {
    let $data := (1, 2)
    return ser:serialize-with-item-separator($data, "xml")
};

declare
    %test:assertEquals("1--2")
function ser:item-separator-adaptive-method() {
    let $data := (1, 2)
    return ser:serialize-with-item-separator($data, "adaptive")
};

declare
    %test:assertEquals("1--2")
function ser:test() {
    let $data := (1, 2)
    return ser:serialize-with-item-separator($data, "xml")
};


updated index syntax

updated index syntax

(: --------------------------------------------------------------------- :)
declare index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string;

(:
declare index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string;
:)

(: --------------------------------------------------------------------- :)
declare unique index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string;

(:
declare unique index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string;
:)

(: --------------------------------------------------------------------- :)
declare non unique index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string;

(:
declare non unique index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string;
:)

(: --------------------------------------------------------------------- :)
declare ordered index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string;

(:
declare value range index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string;
:)

(: --------------------------------------------------------------------- :)
declare ordered index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string;

(:
declare value range index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string;
:)

(: --------------------------------------------------------------------- :)
declare unordered index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string;

(:
declare value equality index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string;
:)

(: --------------------------------------------------------------------- :)
declare automatic index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string;

(:
declare automatically maintained index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string;
:)

(: --------------------------------------------------------------------- :)
declare manual index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string;

(:
declare explicitly maintained index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string;
:)

(: --------------------------------------------------------------------- :)
declare unique ordered automatic index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string;

(:
declare unique value range automatically maintained index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string;
:)

(: --------------------------------------------------------------------- :)
declare index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string ascending empty greatest;

(:
declare index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string ascending empty greatest;
:)

(: --------------------------------------------------------------------- :)
declare index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string ascending empty least;

(:
declare index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string ascending empty least;
:)

(: --------------------------------------------------------------------- :)
declare index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string ascending;

(:
declare index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string ascending;
:)

(: --------------------------------------------------------------------- :)
declare index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string ascending,
     ./@id2 as xs:integer descending;

(:
declare index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string ascending,
     $e/@id2 as xs:integer descending;
:)

(: --------------------------------------------------------------------- :)
declare index foo:bar on xqddf:collection(coll:foo)
  by ./@id as xs:string ascending empty least collation "http://foo.com/bar",
     ./@id2 as xs:integer descending;

(:
declare index foo:bar on nodes $e in xqddf:collection(coll:foo)
  by $e/@id as xs:string ascending empty least collation "http://foo.com/bar",
     $e/@id2 as xs:integer descending;
:)

1


changed variable names

changed variable names

import module namespace csd_dm = "https://github.com/openhie/openinfoman/csd_dm";
import module namespace csd_webconf =  "https://github.com/openhie/openinfoman/csd_webconf";
import module namespace uuid = "https://github.com/openhie/openinfoman-datim/uuid";
declare namespace csd  =  "urn:ihe:iti:csd:2013";
let $facilities_service_dir := "Facilities"
let $CHW_doc_name := "CHW"
let $doc :=  csd_dm:open_document($csd_webconf:db,$facilities_service_dir)
let $chw_file := file:read-text("./chw.json")
let $json := json:parse($chw_file)
let $data :=
<csd:CSD xmlns:csd="urn:ihe:iti:csd:2013">
  <csd:organizationDirectory/>
  <csd:serviceDirectory/>
  <csd:facilityDirectory/>
  <csd:providerDirectory>
{
for $record in $json/json/_
let $facility_uuid := string($doc//csd:facility[string(./csd:otherID[@code="code"])=data($record/health__centre____code)]/@entityID)
let $referal_facility_uuid := string($doc//csd:facility[string(./csd:otherID[@code="code"])=data($record/referral__hospital____code)]/@entityID)
return
    <csd:provider xmlns:csd="urn:ihe:iti:csd:2013" entityID="{concat("urn:uuid:",random:uuid())}">
      <csd:demographic>
        <csd:name>
          <csd:commonName>{fn:normalize-space(concat(data($record/given__name),data($record/surname)))}</csd:commonName>
          <csd:surname>{fn:normalize-space(data($record/surname))}</csd:surname>
          <csd:forename>{fn:normalize-space(data($record/given__name))}</csd:forename>
        </csd:name>
        <csd:gender>{data($record/sex)}</csd:gender>
        <csd:dateOfBirth>{data($record/date__of__birth)}</csd:dateOfBirth>
      </csd:demographic>
      <csd:facilities>
        <csd:facility entityID="{$facility_uuid}">
        </csd:facility>
      </csd:facilities>
      <csd:referalHospital entityID="{$referal_facility_uuid}"></csd:referalHospital>
    </csd:provider>
}
</csd:providerDirectory>
</csd:CSD>
return
csd_dm:add($csd_webconf:db,$data,$CHW_doc_name)

import module namespace csd_dm = "https://github.com/openhie/openinfoman/csd_dm";
import module namespace csd_webconf =  "https://github.com/openhie/openinfoman/csd_webconf";
import module namespace uuid = "https://github.com/openhie/openinfoman-datim/uuid";
declare namespace csd  =  "urn:ihe:iti:csd:2013";
let $facilities_doc_name := "DHIS2-Facilities"
let $CHW_doc_name := "CHW"
let $doc :=  csd_dm:open_document($csd_webconf:db,$facilities_doc_name)
let $file := file:read-text("./data.json")
let $json := json:parse($file)
let $data :=
<csd:CSD xmlns:csd="urn:ihe:iti:csd:2013">
  <csd:organizationDirectory/>
  <csd:serviceDirectory/>
  <csd:facilityDirectory/>
  <csd:providerDirectory>
{
for $record in $json/json/_
let $facility_uuid := string($doc//csd:organization[string(./csd:otherID[@code="code"])=data($record/health__centre____code)]/@entityID)
let $referal_facility_uuid := string($doc//csd:organization[string(./csd:otherID[@code="code"])=data($record/referral_hospital__code)]/@entityID)
return
    <csd:provider xmlns:csd="urn:ihe:iti:csd:2013" entityID="{concat("urn:uuid:",random:uuid())}">
      <csd:demographic>
        <csd:name>
          <csd:commonName>{fn:normalize-space(concat(data($record/given__name),data($record/surname)))}</csd:commonName>
          <csd:surname>{fn:normalize-space(data($record/surname))}</csd:surname>
          <csd:forename>{fn:normalize-space(data($record/given__name))}</csd:forename>
        </csd:name>
        <csd:gender>{data($record/sex)}</csd:gender>
        <csd:dateOfBirth>{data($record/date__of__birth)}</csd:dateOfBirth>
      </csd:demographic>
      <csd:facilities>
        <csd:facility entityID="{$facility_uuid}">
        </csd:facility>
      </csd:facilities>
      <csd:referalHospital entityID="{$referal_facility_uuid}"></csd:referalHospital>
    </csd:provider>
}
</csd:providerDirectory>
</csd:CSD>
return
csd_dm:add($csd_webconf:db,$data,$CHW_doc_name)


[bugfix] fixed wrong sidebar links (due to xinclude using a wrong base directory) in documenation search results.

svn path=/trunk/eXist/; revision=9855

xquery version "1.0";

import module namespace request="http://exist-db.org/xquery/request";

declare namespace dq="http://exist-db.org/xquery/documentation";

declare option exist:serialize "method=xhtml media-type=text/html add-exist-id=all highlight-matches=all expand-xincludes=yes";

let $path := request:get-parameter("path", ())
let $query := request:get-parameter("q", ())
let $doc := util:eval(concat("doc($path)/*[", $query, "]"))
return
	transform:stream-transform($doc, "../stylesheets/db2html.xsl", (),
		"expand-xincludes=yes add-exist-id=all highlight-matches=all xinclude-path=..")

xquery version "1.0";

import module namespace request="http://exist-db.org/xquery/request";

declare namespace dq="http://exist-db.org/xquery/documentation";

declare option exist:serialize "method=xhtml media-type=text/html add-exist-id=all highlight-matches=all expand-xincludes=yes";

let $path := request:get-parameter("path", ())
let $query := request:get-parameter("q", ())
let $doc := util:eval(concat("doc($path)/*[", $query, "]"))
return
	transform:stream-transform($doc, "../stylesheets/db2html.xsl", (),
		"expand-xincludes=yes add-exist-id=all highlight-matches=all")


Bugfix: mongo collection must be removed for each test

xquery version "3.0";

module namespace support="http://exist-db.org/ext/mongodb/test/support";

import module namespace mongodb = "http://exist-db.org/xquery/mongodb"
                at "java:org.exist.mongodb.xquery.MongodbModule";

declare variable $support:mongoUrl := "mongodb://miniserver.local";
declare variable $support:database := "mydatabase";
declare variable $support:testCollection := "/db/mongodbTest";
declare variable $support:mongoCollection := "mongodbTest";
declare variable $support:tokenStore := "token.xml";

(:
 : Connect to mongodb, store token
 :)
declare function support:setup() {
    let $foo :=  xmldb:create-collection("/db", "mongodbTest")
    let $token := mongodb:connect($support:mongoUrl)
    return xmldb:store($support:testCollection, $support:tokenStore, <token>{$token}</token>)
};

(:
 : Disconnect from mongodb, cleanup token
 :)
declare function support:cleanup() {
    let $mongodbClientId := support:getToken()
    let $drop := mongodb:drop($mongodbClientId, $support:database, $support:mongoCollection)
    let $logout := mongodb:close($mongodbClientId)
    return
    xmldb:remove($support:testCollection)
};

(:
 : Get token from store
 :)
declare function support:getToken() as xs:string {
    doc($support:testCollection || "/" || $support:tokenStore )//token/text()
};

xquery version "3.0";

module namespace support="http://exist-db.org/ext/mongodb/test/support";

import module namespace mongodb = "http://exist-db.org/xquery/mongodb"
                at "java:org.exist.mongodb.xquery.MongodbModule";

declare variable $support:mongoUrl := "mongodb://miniserver.local";
declare variable $support:database := "mydatabase";
declare variable $support:testCollection := "/db/mongodbTest";
declare variable $support:mongoCollection := "mongodbTest";
declare variable $support:tokenStore := "token.xml";

(:
 : Connect to mongodb, store token
 :)
declare function support:setup() {
    let $foo :=  xmldb:create-collection("/db", "mongodbTest")
    let $token := mongodb:connect($support:mongoUrl)
    return xmldb:store($support:testCollection, $support:tokenStore, <token>{$token}</token>)
};

(:
 : Disconnect from mongodb, cleanup token
 :)
declare function support:cleanup() {
    let $mongodbClientId := support:getToken()
    let $logout := mongodb:close($mongodbClientId)
    return
    xmldb:remove($support:testCollection)
};

(:
 : Get token from store
 :)
declare function support:getToken() as xs:string {
    doc($support:testCollection || "/" || $support:tokenStore )//token/text()
};


anon email too

anon email too

module namespace anonymize = "https://github.com/openhie/openinfoman-anon";
import module namespace functx = "http://www.functx.com";

declare namespace csd  =  "urn:ihe:iti:csd:2013";

declare variable $anonymize:exclude_address := (
  'street',  'st',  'way',  'road',  'hwy',  'highway' , 'lane','ave','avenue', 'rd', 's', 'n', 'e','w','sw','nw','se','ne'
);

declare variable $anonymize:exclude_name := (
  'clinic','hospital','hosp','facility','health','primary','district','regional','referal','center','centre'
);

declare function anonymize:document2($src_doc,$provider_values,$organization_values,$facility_values) {
  $src_doc
};
declare function anonymize:document($src_doc,$provider_values,$organization_values,$facility_values) {
   <csd:CSD>
     <csd:organizationDirectory>
       {
	 for $org in $src_doc/csd:CSD/csd:organizationDirectory/csd:organization
	 return anonymize:organization($org,$organization_values)
       }
     </csd:organizationDirectory>
     <csd:facilityDirectory>
       {
	 for $fac in $src_doc/csd:CSD/csd:facilityDirectory/csd:facility
	 return anonymize:facility($fac,$facility_values)
       }
     </csd:facilityDirectory>
     <csd:serviceDirectory>{$src_doc/csd:CSD/csd:serviceDirectory/csd:service}</csd:serviceDirectory>
     <csd:providerDirectory>
       {
	 for $provider in $src_doc/csd:CSD/csd:providerDirectory/csd:provider
	 return anonymize:provider($provider,$provider_values,$facility_values)
       }
     </csd:providerDirectory>
   </csd:CSD>
};

declare function anonymize:scramble($source) {
  if (contains($source,'@'))
  then (:looks like email :)
    concat('someone_' , random:integer() , '@nowhere.com')
  else
    let $tokens := functx:chars($source)
    let $all :=
    for $p in (1 to count($tokens))
      let $t := $tokens[$p]
      return
	if (matches($t,'\d'))
	then string(random:integer(max((0,9)))+1)
	else $t
    return string-join($all,'')

};

declare function anonymize:replace-word($source,$values) {
  anonymize:replace-word($source,$values,map {})
};

declare function anonymize:replace-word($source,$values,$map) {
  anonymize:replace-word($source,$values,$map,())
};

declare function anonymize:replace-word($source,$values,$map,$excludes) {
  let $mapped := map:get($map,$source)
  return
    if ($mapped)
    then $mapped
    else if ($excludes = lower-case($source) )
    then $source
    else if (matches($source,"\d"))
    then anonymize:scramble($source)
    else
      let $rand := random:integer(count($values)) + 1
      return $values[$rand]
};

declare function anonymize:replace-string($source,$values){
  anonymize:replace-string($source,$values,map {})
};

declare function anonymize:replace-string($source,$values,$map) {
  anonymize:replace-string($source,$values,$map,())
};

declare function anonymize:replace-string($source,$values,$map,$excludes) {
  (:tokenize the $source text on non-letters, replace with value and join:)
  let $tokens := tokenize($source,'\W+')
  let $joins := tokenize($source,'\w+')
  let $anons :=
    for $t in $tokens
    return anonymize:replace-word($t,$values,$map,$excludes)
  let $count := max((count($anons), count($joins)))
  let $all :=
    if (matches($source,'^\W+'))
    then
      for $p in (0 to $count)
      return ($anons[$p],$joins[$p])
    else
      for $p in (0 to $count)
      return ($joins[$p],$anons[$p])
  return string-join($all)

};

declare function  anonymize:organization($organization,$values) {
  anonymize:organization($organization,$values,map{})
};

declare function  anonymize:organization($organization,$values,$map) {
  copy $org  := $organization
  modify (
    let $anon_name := anonymize:replace-string($org/csd:primaryName,$values,$map ,$anonymize:exclude_name)
    return replace value of node $org/csd:primaryName with $anon_name
    ,
    for $cp in $org/csd:contactPoint
    let $anon_cp :=
      if (string($cp/@code) = 'EMAIL')
      then
        <csd:contactPoint>
          <csd:codedType code="{$cp/csd:codedType/@code}" codingScheme="{$cp/csd:codedType/@codingScheme}">someone@nowhere.com</csd:codedType>
	</csd:contactPoint>
      else
        <csd:contactPoint>
          <csd:codedType code="{$cp/csd:codedType/@code}" codingScheme="{$cp/csd:codedType/@codingScheme}">{anonymize:scramble($cp/csd:codedType/text())}</csd:codedType>
	</csd:contactPoint>
    return replace node $cp with $anon_cp
    ,
    for $addr in $org/csd:address
      for $line in $addr/csd:addressLine[@component = 'streetAddress' or @component = 'StreetAddress' or @component = 'city']
      let $anon_addr := anonymize:replace-string($line/text(),$values,$map, $anonymize:exclude_address)
      return  replace value of node $line with $anon_addr
    ,
    for $contact_name in $org/csd:contact/csd:person/csd:name
    let $anon_name := anonymize:provider-name($contact_name,$values)
    return replace node $contact_name with $anon_name
    ,
    for $addr in $org/csd:contact/csd:person/csd:address
      for $line in $addr/csd:addressLine[@component = 'streetAddress' or @component = 'StreetAddress' or @component = 'city']
      let $anon_addr := anonymize:replace-string($line/text(),$values,$map, $anonymize:exclude_address)
      return replace value of node $line with $anon_addr

  )
  return $org
};

declare function  anonymize:facility($facility,$values) {
  anonymize:facility($facility,$values,map {})
};

declare function  anonymize:facility($facility,$values,$map) {
  copy $fac  := $facility
  modify (
    let $anon_name := anonymize:replace-string($fac/csd:primaryName,$values,$map,$anonymize:exclude_name)
    return replace value of node $fac/csd:primaryName with $anon_name
    ,
    for $cp in $fac/csd:contactPoint
    let $anon_cp :=
      <csd:contactPoint>
        <csd:codedType code="{$cp/csd:codedType/@code}" codingScheme="{$cp/csd:codedType/@codingScheme}">{anonymize:scramble($cp/csd:codedType/text())}</csd:codedType>
      </csd:contactPoint>
    return replace node $cp with $anon_cp
    ,
    for $addr in $fac/csd:address
      for $line in $addr/csd:addressLine[@component = 'streetAddress' or @component = 'StreetAddress' or  @component = 'city']
      let $anon_addr :=  anonymize:replace-string($line/text(),$values,$map,$anonymize:exclude_address)
      return replace value of node $line with $anon_addr
    ,
    for $contact_name in $fac/csd:contact/csd:person/csd:name
    let $anon_name := anonymize:provider-name($contact_name,$values)
    return replace node $contact_name with $anon_name
    ,
    for $addr in $fac/csd:contact/csd:person/csd:address
      for $line in $addr/csd:addressLine[@component = 'streetAddress' or @component = 'StreetAddress' or  @component = 'city']
      let $anon_addr := anonymize:replace-string($line/text(),$values,$map, $anonymize:exclude_address)
      return replace value of node $line with $anon_addr

  )
  return $fac
};

declare function anonymize:provider($provider,$values,$addr_values) {
  anonymize:provider($provider,$values,$addr_values,map {})
};

declare function anonymize:provider($provider,$values,$addr_values,$map) {
  copy $prov := $provider
  modify (
    for $name in $prov/csd:demographic/csd:name
    let $anon_name := anonymize:provider-name($name,$values)
    return replace node $name with $anon_name
    ,
    for $cp in $prov/csd:demographic/csd:contactPoint
      let $anon_cp :=
      <csd:contactPoint>
        <csd:codedType code="{$cp/csd:codedType/@code}" codingScheme="{$cp/csd:codedType/@codingScheme}">{anonymize:scramble($cp/csd:codedType/text())}</csd:codedType>
      </csd:contactPoint>
      return replace node $cp with $anon_cp
    ,
    for $addr in $prov/csd:demographic/csd:address
      for $line in $addr/csd:addressLine[@component = 'streetAddress' or @component = 'StreetAddress' or @component = 'city']
      let $anon_addr := anonymize:replace-string($line/text(),$addr_values,$map, $anonymize:exclude_address)
      return  replace value of node $line with $anon_addr

    )
  return $prov

};

declare function anonymize:provider-name($name,$values) {
(: Example Input:
				<name>
					<commonName>Banargee, Dev</commonName>
					<honorific>Dr.</honorific>
					<forename>Dev</forename>
					<surname>Banerjee</surname>
				</name>
:)
    let $honor :=  ($name/csd:honorific)[1]/text()
    let $sur :=  ($name/csd:surname)[1]/text()
    let $fore :=  ($name/csd:foreame)[1]/text()
    let $common :=  ($name/csd:commonName)[1]/text()
    let $anon_sur := anonymize:replace-string($sur,$values)
    let $anon_fore := anonymize:replace-string($fore,$values)

    let $map_0 :=
      if ($honor)
      then map {$honor: $honor}
      else map {}
    let $map_1 :=
      if ($anon_sur)
      then map:put($map_0,$sur,$anon_sur)
      else $map_0
    let $map_2 :=
      if ($anon_fore)
      then map:put($map_0,$fore,$anon_fore)
      else $map_1

    let $anon_common := anonymize:replace-string($common,$values,$map_2)
    let $anon_name :=
      <csd:name>
         <csd:commonName>{$anon_common}</csd:commonName>
	 {if ($honor) then <csd:honorific>{$honor}</csd:honorific> else () }
	 {if ($anon_fore) then	 <csd:forename>{$anon_fore}</csd:forename> else () }
	 {if ($anon_sur) then  <csd:surname>{$anon_sur}</csd:surname> else () }
      </csd:name>
    return $anon_name
};

import module namespace csd_webconf =  "https://github.com/openhie/openinfoman/csd_webconf";
import module namespace csd_lsc = "https://github.com/openhie/openinfoman/csd_lsc";
import module namespace csd_dm = "https://github.com/openhie/openinfoman/csd_dm";
import module namespace anonymize = "https://github.com/openhie/openinfoman-anon";
import module namespace functx = "http://www.functx.com";

declare namespace csd  =  "urn:ihe:iti:csd:2013";

declare variable $careServicesRequest as item() external;

let $dest_doc := /.
let $dest := $careServicesRequest/@resource

let $values_doc := "anonymous/bible.xml"
let $fac_values_doc := "anonymous/star.xml"

let $values_src_0 := db:open($csd_webconf:db,  $values_doc)
let $values_src_1 :=
 if (count($values_src_0//value[1]) > 0)
 then $values_src_0
 else
   let $number-for-a := string-to-codepoints('A')
   let $number-for-z := string-to-codepoints('Z')

   let $values_src :=
     <values>
       {
	 for $letter in ($number-for-a to $number-for-z)
	 let $url := concat('http://en.wikipedia.org/wiki/List_of_biblical_names_starting_with_', codepoints-to-string($letter))
	 let $resp := http:send-request(<http:request method='get' href="{$url}"/>)
 	   for $li in $resp/html/body//div[@id="mw-content-text"]/ul[1]/li
	   let $text := string-join(($li/a[1]/text(),$li/text()))
	   let $name := tokenize($text,'\W+')[1]
	   return <value>{functx:trim($name)}</value>
       }
     </values>
    return $values_src
let $values := $values_src_1//value/text()

let $fac_values_src_0 := db:open($csd_webconf:db,  $fac_values_doc)
let $fac_values_src_1 :=
 if (count($fac_values_src_0//value[1]) > 0)
 then $fac_values_src_0
 else
   let $fac_url := 'http://en.wikipedia.org/wiki/List_of_proper_names_of_stars_in_alphabetical_order'
   let $resp := http:send-request(<http:request method='get' href="{$fac_url}"/>)

   return
     <values>
       {
	 for $td in $resp//table[@class="wikitable"]//td[1]
	 let $text :=
	   functx:trim(string-join(($td/a[1]/text(),$td/text())))
	 return if ($text) then <value>{$text}</value> else ()
       }
     </values>

let $fac_values := $fac_values_src_1//value/text()

return
(
  if (count($values_src_0//value[1]) = 0)
  then
     if (db:exists($csd_webconf:db, $values_doc))
     then db:replace($csd_webconf:db, $values_src_1, $values_doc)
     else db:add($csd_webconf:db, $values_src_1, $values_doc)
  else ()
  ,
  if (count($fac_values_src_0//value[1]) = 0)
  then
     if (db:exists($csd_webconf:db, $fac_values_doc))
     then db:replace($csd_webconf:db, $fac_values_src_1, $fac_values_doc)
     else db:add($csd_webconf:db, $fac_values_src_1, $fac_values_doc)
  else ()
  ,
  for $doc  in $careServicesRequest/documents/document
    let $name := $doc/@resource
    let $src_doc :=
      if (not ($name = $dest)) then csd_dm:open_document($csd_webconf:db, $name)
      else ()
    let $anon_doc := anonymize:document($src_doc,$values,$fac_values,$fac_values)
    return   (csd_lsc:refresh_doc($dest_doc, $anon_doc))

)


Address #56 - Builtin Saxon functions: add `java-type` namespace declaration; add annotations for PE/EE.

xquery version "1.0";
(:~
 : Saxon extension functions
 : @see http://www.saxonica.com/html/documentation/functions/saxon
 :
 :)
module namespace saxon = "http://saxon.sf.net/";

declare namespace jt = "http://saxon.sf.net/java-type";

declare namespace a = "http://reecedunn.co.uk/xquery/annotations";
declare namespace o = "http://reecedunn.co.uk/xquery/options";

declare %a:since("saxon/pe", "9.2") %a:since("saxon/ee", "9.2") function saxon:adjust-to-civil-time($in as xs:dateTime, $tz as xs:string) as xs:dateTime? external; (: reqs PE or EE :)
declare %a:since("saxon/pe", "9.8") function saxon:array-member($value as item()*) as jt:com.saxonica.functions.extfn.ArrayMemberValue external; (: http://www.saxonica.com/html/documentation/functions/saxon/array-member.html? how to indicate namespaces there? :)
declare %a:since("saxon/pe", "8.1") %a:since("saxon/ee", "8.1") function saxon:base64Binary-to-octets($input as xs:base64Binary) as xs:integer* external;
declare %a:since("saxon/pe", "8.5") %a:since("saxon/ee", "8.5") function saxon:base64Binary-to-string($input as xs:base64Binary?, $encoding as xs:string) as xs:string external;

xquery version "1.0";
(:~
 : Saxon extension functions
 : @see http://www.saxonica.com/html/documentation/functions/saxon
 :
 :)
module namespace saxon = "http://saxon.sf.net/";

declare namespace a = "http://reecedunn.co.uk/xquery/annotations";
declare namespace o = "http://reecedunn.co.uk/xquery/options";

declare %a:since("saxon", "9.2") function saxon:adjust-to-civil-time($in as xs:dateTime, $tz as xs:string) as xs:dateTime? external; (: reqs PE or EE :)
declare %a:since("saxon", "9.8") function saxon:array-member($value as item()*) as jt:com.saxonica.functions.extfn.ArrayMemberValue external; (: http://www.saxonica.com/html/documentation/functions/saxon/array-member.html? how to indicate namespaces there? :)
declare %a:since("saxon", "8.1") function saxon:base64Binary-to-octets($input as xs:base64Binary) as xs:integer* external;
declare %a:since("saxon", "8.5") function saxon:base64Binary-to-string($input as xs:base64Binary?, $encoding as xs:string) as xs:string external;


changed @oid to @entryID

changed @oid to @entryID

import module namespace csd_bl = "https://github.com/openhie/openinfoman/csd_bl";
declare default element  namespace   "urn:ihe:iti:csd:2013";
declare variable $careServicesRequest as item() external;

(:
   The query will be executed against the root element of the CSD document.

   The dynamic context of this query has $careServicesRequest set to contain any of the search
   and limit paramaters as sent by the Service Finder
:)

<CSD xmlns:csd="urn:ihe:iti:csd:2013"  >
  <organizationDirectory/>
  <serviceDirectory/>
  <facilityDirectory/>
  <providerDirectory>
    {
      let $facility_entityID := $careServicesRequest/facility[1]/@entityID
      let $service_entityID := $careServicesRequest/facility[1]/service[1]/@entityID

      (: if no provider id was provided, then this is invalid. :)
      let $provs0 := if (exists($careServicesRequest/id))
	then csd_bl:filter_by_primary_id(/CSD/providerDirectory/*,$careServicesRequest/id)
      else ()

      let $provs1 := if (exists($facility_entityID) and count($provs0) = 1)
	then
	   if (count ($provs0[1]/facilities/facility[@entityID = $facility_entityID]) > 0) then $provs0 else ()
	else $provs0

      let $provs2 := if (exists($service_entityID) and count($provs1) = 1)
	then
	   if (count ($provs1[1]/facilities/facility[upper-case(@entityID) = upper-case($facility_entityID)]/service[upper-case(@entityID) = upper-case($service_entityID)]) > 0) then $provs1 else ()
	else $provs1

      return if (count($provs2) = 1) then
	<provider entityID='{$provs2[1]/@entityID}'/>
      else
	 ()
    }
  </providerDirectory>
</CSD>

import module namespace csd_bl = "https://github.com/openhie/openinfoman/csd_bl";
declare default element  namespace   "urn:ihe:iti:csd:2013";
declare variable $careServicesRequest as item() external;

(:
   The query will be executed against the root element of the CSD document.

   The dynamic context of this query has $careServicesRequest set to contain any of the search
   and limit paramaters as sent by the Service Finder
:)

<CSD xmlns:csd="urn:ihe:iti:csd:2013"  >
  <organizationDirectory/>
  <serviceDirectory/>
  <facilityDirectory/>
  <providerDirectory>
    {
      let $facility_oid := $careServicesRequest/facility[1]/@oid
      let $service_oid := $careServicesRequest/facility[1]/service[1]/@oid

      (: if no provider id was provided, then this is invalid. :)
      let $provs0 := if (exists($careServicesRequest/id))
	then csd_bl:filter_by_primary_id(/CSD/providerDirectory/*,$careServicesRequest/id)
      else ()

      let $provs1 := if (exists($facility_oid) and count($provs0) = 1)
	then
	   if (count ($provs0[1]/facilities/facility[@oid = $facility_oid]) > 0) then $provs0 else ()
	else $provs0

      let $provs2 := if (exists($service_oid) and count($provs1) = 1)
	then
	   if (count ($provs1[1]/facilities/facility[@oid = $facility_oid]/service[@oid = $service_oid]) > 0) then $provs1 else ()
	else $provs1

      return if (count($provs2) = 1) then
	<provider oid='{$provs2[1]/@oid}'/>
      else
	 ()
    }
  </providerDirectory>
</CSD>


[MIN] DBA: Saving queries (#2030, 7e1040ea7430d4e5d264a2fd1bce8fc79eedfa30)

(:~
 : Save query.
 :
 : @author Christian Grün, BaseX Team 2005-21, BSD License
 :)
module namespace dba = 'dba/queries';

import module namespace config = 'dba/config' at '../lib/config.xqm';

(:~
 : Saves a query file and returns the list of stored queries.
 : @param  $name   name of query file
 : @param  $query  query string
 : @return names of stored queries
 :)
declare
  %rest:POST('{$query}')
  %rest:path('/dba/query-save')
  %rest:query-param('name', '{$name}')
  %output:method('text')
function dba:query-save(
  $name   as xs:string,
  $query  as xs:string?
) as xs:string {
  let $path := config:directory() || $name
  return (
    try {
      prof:void(xquery:parse(string($query), map {
        'plan': false(), 'pass': true(), 'base-uri': $path
      }))
    } catch * {
      error($err:code, 'Query was not stored: ' || $err:description, $err:value)
    },
    config:query($name),
    file:write-text($path, $query),
    string-join(config:query-files(), '/')
  )
};

(:~
 : Save query.
 :
 : @author Christian Grün, BaseX Team 2005-21, BSD License
 :)
module namespace dba = 'dba/queries';

import module namespace config = 'dba/config' at '../lib/config.xqm';

(:~
 : Saves a query file and returns the list of stored queries.
 : @param  $name   name of query file
 : @param  $query  query string
 : @return names of stored queries
 :)
declare
  %rest:POST('{$query}')
  %rest:path('/dba/query-save')
  %rest:query-param('name', '{$name}')
  %output:method('text')
function dba:query-save(
  $name   as xs:string,
  $query  as xs:string?
) as xs:string {
  let $path := config:directory() || $name
  return (
    try {
      prof:void(xquery:parse($query, map {
        'plan': false(), 'pass': true(), 'base-uri': $path
      }))
    } catch * {
      error($err:code, 'Query was not stored: ' || $err:description, $err:value)
    },
    config:query($name),
    file:write-text($path, $query),
    string-join(config:query-files(), '/')
  )
};