Change the structure of the tests.

Change the structure of the tests.

Test cases and display remain the same.

import module namespace eval = "http://expath.org/ns/invoker" at "lib/invoker.xqy";

declare namespace h = "http://expath.org/ns/invoker/test/hello";
declare namespace l = "http://expath.org/ns/invoker/test/libdules";

(:~~~~~
 : Functions to be called/invoked in tests.
 :)

declare function local:hello() {
   local:hello('world')
};

declare function local:hello-doc() {
   local:hello(fn:doc('/who.xml'))
};

declare function local:hello($who as xs:string) {
   'Hello, ' || $who || '!'
};

(:~~~~~
 : Test wrapper for eval:invoke functions.
 :)

declare function local:invoke(
   $arg1 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string,
   $cmp  as xs:string
)
{
   local:test(
      eval:invoke($arg1),
      $exp, 'invoke', $what, $how, $cmp)
};

declare function local:invoke(
   $arg1 as item()*,
   $arg2 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string,
   $cmp  as xs:string
)
{
   local:test(
      eval:invoke($arg1, $arg2),
      $exp, 'invoke', $what, $how, $cmp)
};

declare function local:invoke(
   $arg1 as item()*,
   $arg2 as item()*,
   $arg3 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string,
   $cmp  as xs:string
)
{
   local:test(
      eval:invoke($arg1, $arg2, $arg3),
      $exp, 'invoke', $what, $how, $cmp)
};

declare function local:invoke(
   $arg1 as item()*,
   $arg2 as item()*,
   $arg3 as item()*,
   $arg4 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string,
   $cmp  as xs:string
)
{
   local:test(
      eval:invoke($arg1, $arg2, $arg3, $arg4),
      $exp, 'invoke', $what, $how, $cmp)
};

declare function local:invoke(
   $arg1 as item()*,
   $arg2 as item()*,
   $arg3 as item()*,
   $arg4 as item()*,
   $arg5 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string,
   $cmp  as xs:string
)
{
   local:test(
      eval:invoke($arg1, $arg2, $arg3, $arg4, $arg5),
      $exp, 'invoke', $what, $how, $cmp)
};

(:~~~~~
 : Test wrapper for eval:call functions.
 :)

declare function local:call(
   $arg1 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string
)
{
   local:test(
      eval:call($arg1),
      $exp, 'call', $what, $how)
};

declare function local:call(
   $arg1 as item()*,
   $arg2 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string
)
{
   local:test(
      eval:call($arg1, $arg2),
      $exp, 'call', $what, $how)
};

declare function local:call(
   $arg1 as item()*,
   $arg2 as item()*,
   $arg3 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string
)
{
   local:test(
      eval:call($arg1, $arg2, $arg3),
      $exp, 'call', $what, $how)
};

declare function local:call(
   $arg1 as item()*,
   $arg2 as item()*,
   $arg3 as item()*,
   $arg4 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string
)
{
   local:test(
      eval:call($arg1, $arg2, $arg3, $arg4),
      $exp, 'call', $what, $how)
};

declare function local:call(
   $arg1 as item()*,
   $arg2 as item()*,
   $arg3 as item()*,
   $arg4 as item()*,
   $arg5 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string
)
{
   local:test(
      eval:call($arg1, $arg2, $arg3, $arg4, $arg5),
      $exp, 'call', $what, $how)
};

(:~~~~~
 : Test wrapper for eval:module functions.
 :)

declare function local:module(
   $arg1 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string
)
{
   local:test(
      eval:module($arg1),
      $exp, 'module', $what, $how)
};

declare function local:module(
   $arg1 as item()*,
   $arg2 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string
)
{
   local:test(
      eval:module($arg1, $arg2),
      $exp, 'module', $what, $how)
};

declare function local:module(
   $arg1 as item()*,
   $arg2 as item()*,
   $arg3 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string
)
{
   local:test(
      eval:module($arg1, $arg2, $arg3),
      $exp, 'module', $what, $how)
};

declare function local:module(
   $arg1 as item()*,
   $arg2 as item()*,
   $arg3 as item()*,
   $arg4 as item()*,
   $exp  as xs:string,
   $what as xs:string,
   $how  as xs:string
)
{
   local:test(
      eval:module($arg1, $arg2, $arg3, $arg4),
      $exp, 'module', $what, $how)
};

(:~~~~~
 : Test result formatting functions.
 :)

declare function local:test(
   $res  as item()*,
   $exp  as xs:string,
   $name as xs:string,
   $what as xs:string,
   $how  as xs:string
)
{
   local:test($res, $exp, $name, $what, $how, ())
};

declare function local:test(
   $res  as item()*,
   $exp  as xs:string,
   $name as xs:string,
   $what as xs:string,
   $how  as xs:string,
   $cmp  as xs:string?
)
{
   element { $name } {
      attribute { 'component' } { $cmp }[$cmp],
      attribute { 'what' } { $what },
      attribute { 'how' } { $how },
      $res
   }
};

(:~~~~~
 : Actual test cases.
 :)

<result>

<!-- invokes -->

{
   local:invoke(
      <eval:function name="l:hello" xmlns:l="http://www.w3.org/2005/xquery-local-functions"/>,
      'Hello, world!', 'name', 'both', 'function'),

   local:invoke(
      <eval:module href="/hello-world.xqy"/>,
      'Hello, world!', 'href', 'both', 'module'),

   local:invoke(
      <dummy>
         <eval:module href="/hello-world.xqy" id="me"/>
      </dummy>,
      'me',
      'Hello, world!', 'id', 'both', 'module'),

   local:invoke(
      <eval:module href="/hello-doc.xqy"/>,
      (),
      'Documents',
      'Hello, document!', 'db', 'param', 'module'),

   local:invoke(
      <eval:module href="/hello-doc.xqy" db="Documents"/>,
      'Hello, document!', 'db', 'elem', 'module'),

   local:invoke(
      <eval:module href="/hello-modules.xqy"/>,
      (),
      (),
      'invoker-db-two',
      'Hello, modules!', 'modules', 'param', 'module'),

   local:invoke(
      <eval:module href="/hello-modules.xqy" modules-db="invoker-db-two"/>,
      'Hello, modules!', 'modules', 'elem', 'module'),

   local:invoke(
      <eval:module href="/hello-world.xqy"/>,
      (),
      (),
      (),
      'xquery',
      'Hello, world!', 'xquery', 'param', 'module'),

   local:invoke(
      <eval:module href="/hello-world.xqy" lang="xquery"/>,
      'Hello, world!', 'xquery', 'elem', 'module'),

   local:invoke(
      <eval:module href="/hello-world.sjs"/>,
      (),
      (),
      (),
      'js',
      'Hello, js!', 'javascript', 'param', 'module'),

   local:invoke(
      <eval:module href="/hello-world.sjs" lang="js"/>,
      'Hello, js!', 'javascript', 'elem', 'module')
}

<!-- calls -->

{
   local:call(
      fn:function-lookup(xs:QName('local:hello'), 0),
      'Hello, world!', 'name', 'param'),

   local:call(
      <dummy name="l:hello" xmlns:l="http://www.w3.org/2005/xquery-local-functions"/>,
      'Hello, world!', 'name', 'elem'),

   local:call(
      local:hello#0,
      'Hello, world!', 'function I', 'param'),

   local:call(
      function() { 'Hello, world!' },
      'Hello, world!', 'function II', 'param'),

   local:call(
      function() { local:hello() },
      'Hello, world!', 'function III', 'param'),

   local:call(
      function() { local:hello('world') },
      'Hello, world!', 'function IV', 'param'),

   (: TODO: What about a JS fun, in an SJS file? :)
   local:call(
      xs:QName('h:hello'), '/hello-lib.xqy',
      'Hello, world!', 'href', 'param'),

   local:call(
      <dummy xmlns:h="http://expath.org/ns/invoker/test/hello"
             name="h:hello" href="/hello-lib.xqy"/>,
      'Hello, world!', 'href', 'elem'),

   local:call(
      local:hello-doc#0, (), 'Documents',
      'Hello, world!', 'db', 'param'),

   local:call(
      <dummy xmlns:l="http://www.w3.org/2005/xquery-local-functions"
             name="l:hello-doc" db="Documents"/>,
      'Hello, world!', 'db', 'elem'),

   local:call(
      xs:QName('l:hello'), '/hello-libdules.xqy', (), 'invoker-db-two',
      'Hello, world!', 'modules', 'param'),

   local:call(
      <dummy xmlns:l="http://expath.org/ns/invoker/test/libdules"
             name="l:hello" href="/hello-libdules.xqy" modules-db="invoker-db-two"/>,
      'Hello, world!', 'modules', 'elem'),

   local:call(
      local:hello#0, (), (), (), 'xquery',
      'Hello, world!', 'xquery', 'param'),

   local:call(
      <dummy xmlns:l="http://www.w3.org/2005/xquery-local-functions"
             name="l:hello" lang="xquery"/>,
      'Hello, world!', 'xquery', 'elem')

   (: TODO: Not supported yet... :)
   (:
   local:call(
      ???, (), (), (), 'js',
      'Hello, world!', 'javascript', 'param')

   local:call(
      <dummy name="hello" lang="js"/>,
      'Hello, world!', 'javascript', 'elem')
   :)
}

<!-- modules -->

{
   local:module(
      '/hello-world.xqy',
      'Hello, world!', 'href', 'param'),

   local:module(
      <dummy href="/hello-world.xqy"/>,
      'Hello, world!', 'href', 'elem'),

   local:module(
      '/hello-doc.xqy', 'Documents',
      'Hello, document!', 'db', 'param'),

   local:module(
      <dummy href="/hello-doc.xqy" db="Documents"/>,
      'Hello, document!', 'db', 'elem'),

   local:module(
      '/hello-modules.xqy', (), 'invoker-db-two',
      'Hello, world!', 'modules', 'param'),

   local:module(
      <dummy href="/hello-modules.xqy" modules-db="invoker-db-two"/>,
      'Hello, world!', 'modules', 'elem'),

   local:module(
      '/hello-world.xqy', (), (), 'xquery',
      'Hello, world!', 'xquery', 'param'),

   local:module(
      <dummy href="/hello-world.xqy" lang="xquery"/>,
      'Hello, world!', 'xquery', 'elem'),

   local:module(
      '/hello-world.sjs', (), (), 'js',
      'Hello, world!', 'javascript', 'param'),

   local:module(
      <dummy href="/hello-world.sjs" lang="js"/>,
      'Hello, world!', 'javascript', 'elem')
}

</result>

import module namespace eval = "http://expath.org/ns/invoker" at "lib/invoker.xqy";

declare namespace h = "http://expath.org/ns/invoker/test/hello";
declare namespace l = "http://expath.org/ns/invoker/test/libdules";

declare function local:hello() {
   local:hello('world')
};

declare function local:hello-doc() {
   local:hello(fn:doc('/who.xml'))
};

declare function local:hello($who as xs:string) {
   'Hello, ' || $who || '!'
};

<result>

<!-- invokes -->

<invoke component="function" what="name"> {
   (: expected: 'Hello, world!' :)
   eval:invoke(
      <eval:function name="l:hello" xmlns:l="http://www.w3.org/2005/xquery-local-functions"/>)
}
</invoke>

<invoke component="module" what="href"> {
   (: expected: 'Hello, world!' :)
   eval:invoke(
      <eval:module href="/hello-world.xqy"/>)
}
</invoke>
<invoke component="module" what="id"> {
   (: expected: 'Hello, world!' :)
   eval:invoke(
      <dummy>
         <eval:module href="/hello-world.xqy" id="me"/>
      </dummy>,
      'me')
}
</invoke>
<invoke component="module" what="db" how="param"> {
   (: expected: 'Hello, document!' :)
   eval:invoke(
      <eval:module href="/hello-doc.xqy"/>,
      (),
      'Documents')
}
</invoke>
<invoke component="module" what="db" how="elem"> {
   (: expected: 'Hello, document!' :)
   eval:invoke(
      <eval:module href="/hello-doc.xqy" db="Documents"/>)
}
</invoke>
<invoke component="module" what="modules" how="param"> {
   (: expected: 'Hello, modules!' :)
   eval:invoke(
      <eval:module href="/hello-modules.xqy"/>,
      (),
      (),
      'invoker-db-two')
}
</invoke>
<invoke component="module" what="modules" how="elem"> {
   (: expected: 'Hello, modules!' :)
   eval:invoke(
      <eval:module href="/hello-modules.xqy" modules-db="invoker-db-two"/>)
}
</invoke>
<invoke component="module" what="xquery" how="param"> {
   (: expected: 'Hello, world!' :)
   eval:invoke(
      <eval:module href="/hello-world.xqy"/>,
      (),
      (),
      (),
      'xquery')
}
</invoke>
<invoke component="module" what="xquery" how="elem"> {
   (: expected: 'Hello, world!' :)
   eval:invoke(
      <eval:module href="/hello-world.xqy" lang="xquery"/>)
}
</invoke>
<invoke component="module" what="javascript" how="param"> {
   (: expected: 'Hello, js!' :)
   eval:invoke(
      <eval:module href="/hello-world.sjs"/>,
      (),
      (),
      (),
      'js')
}
</invoke>
<invoke component="module" what="javascript" how="elem"> {
   (: expected: 'Hello, js!' :)
   eval:invoke(
      <eval:module href="/hello-world.sjs" lang="js"/>)
}
</invoke>

<!-- calls -->

<call what="name" how="param"> {
   (: expected: 'Hello, world!' :)
   eval:call(fn:function-lookup(xs:QName('local:hello'), 0))
}
</call>
<call what="name" how="elem"> {
   (: expected: 'Hello, world!' :)
   eval:call(
      <dummy name="l:hello" xmlns:l="http://www.w3.org/2005/xquery-local-functions"/>)
}
</call>
<call what="function I" how="param"> {
   (: expected: 'Hello, world!' :)
   eval:call(local:hello#0)
}
</call>
<call what="function II" how="param"> {
   (: expected: 'Hello, world!' :)
   eval:call(function() { 'Hello, world!' })
}
</call>
<call what="function III" how="param"> {
   (: expected: 'Hello, world!' :)
   eval:call(function() { local:hello() })
}
</call>
<call what="function IV" how="param"> {
   (: expected: 'Hello, world!' :)
   eval:call(function() { local:hello('world') })
}
</call>
<call what="href" how="param"> {
   (: expected: 'Hello, world!' :)
   eval:call(xs:QName('h:hello'), '/hello-lib.xqy')
}
</call>
<call what="href" how="elem"> {
   (: expected: 'Hello, world!' :)
   eval:call(
      <dummy xmlns:h="http://expath.org/ns/invoker/test/hello"
             name="h:hello" href="/hello-lib.xqy"/>)
}
</call>
<call what="db" how="param"> {
   (: expected: 'Hello, world!' :)
   eval:call(local:hello-doc#0, (), 'Documents')
}
</call>
<call what="db" how="elem"> {
   (: expected: 'Hello, world!' :)
   eval:call(
      <dummy xmlns:l="http://www.w3.org/2005/xquery-local-functions"
             name="l:hello-doc" db="Documents"/>)
}
</call>
<call what="modules" how="param"> {
   (: expected: 'Hello, world!' :)
   eval:call(xs:QName('l:hello'), '/hello-libdules.xqy', (), 'invoker-db-two')
}
</call>
<call what="modules" how="elem"> {
   (: expected: 'Hello, world!' :)
   eval:call(
      <dummy xmlns:l="http://expath.org/ns/invoker/test/libdules"
             name="l:hello" href="/hello-libdules.xqy" modules-db="invoker-db-two"/>)
}
</call>
<call what="xquery" how="param"> {
   (: expected: 'Hello, world!' :)
   eval:call(local:hello#0, (), (), (), 'xquery')
}
</call>
<call what="xquery" how="elem"> {
   (: expected: 'Hello, world!' :)
   eval:call(
      <dummy xmlns:l="http://www.w3.org/2005/xquery-local-functions"
             name="l:hello" lang="xquery"/>)
}
</call>
<!--call what="javascript" how="param"> {
   (: expected: 'Hello, world!' :)
   eval:call(local:hello#0, (), (), (), 'js')
}
</call>
<call what="javascript" how="elem"> {
   (: expected: 'Hello, world!' :)
   eval:call(
      <dummy xmlns:l="http://www.w3.org/2005/xquery-local-functions"
             name="l:hello" lang="js"/>)
}
</call-->

<!-- modules -->

<module what="href" how="param"> {
   (: expected: 'Hello, world!' :)
   eval:module('/hello-world.xqy')
}
</module>
<module what="href" how="elem"> {
   (: expected: 'Hello, world!' :)
   eval:module(
      <dummy href="/hello-world.xqy"/>)
}
</module>
<module what="db" how="param"> {
   (: expected: 'Hello, document!' :)
   eval:module('/hello-doc.xqy', 'Documents')
}
</module>
<module what="db" how="elem"> {
   (: expected: 'Hello, document!' :)
   eval:module(
      <dummy href="/hello-doc.xqy" db="Documents"/>)
}
</module>
<module what="modules" how="param"> {
   (: expected: 'Hello, modules!' :)
   eval:module('/hello-modules.xqy', (), 'invoker-db-two')
}
</module>
<module what="modules" how="elem"> {
   (: expected: 'Hello, modules!' :)
   eval:module(
      <dummy href="/hello-modules.xqy" modules-db="invoker-db-two"/>)
}
</module>
<module what="xquery" how="param"> {
   (: expected: 'Hello, world!' :)
   eval:module('/hello-world.xqy', (), (), 'xquery')
}
</module>
<module what="xquery" how="elem"> {
   (: expected: 'Hello, world!' :)
   eval:module(
      <dummy href="/hello-world.xqy" lang="xquery"/>)
}
</module>
<module what="javascript" how="param"> {
   (: expected: 'Hello, js!' :)
   eval:module('/hello-world.sjs', (), (), 'js')
}
</module>
<module what="javascript" how="elem"> {
   (: expected: 'Hello, js!' :)
   eval:module(
      <dummy href="/hello-world.sjs" lang="js"/>)
}
</module>

</result>


Copied over some heading logic from readinglog python+xquery SimpleHTTPServer code. Minimally tested, especially root and id navigation. Added normalisation information for headers of Readinglog entries.

module namespace logx="http://cefn.com/logx";

declare default element namespace "http://www.w3.org/1999/xhtml";

declare variable $logx:sourceurls as xs:string external;

declare variable $logx:collection := logx:aggregate($logx:sourceurls);

declare variable $logx:authors := "Authors";
declare variable $logx:concepts := "Concepts";
declare variable $logx:field := "Field of Study";
declare variable $logx:methodology := "Methodology";
declare variable $logx:notes := "Notes";
declare variable $logx:quotations := "Quotations";
declare variable $logx:references:= "References";
declare variable $logx:relevance := "Relevance";
declare variable $logx:title := "Title";
declare variable $logx:tags := "Tags";

(:
	Provisional assignment of punctuation to tags
	! = relevance
	? = question
	# = concept
	@ = ...
:)

declare variable $logx:headings := (
	$logx:authors,
	$logx:notes,
	$logx:tags,
	$logx:relevance,
	$logx:quotations,
	$logx:field,
	$logx:concepts,
	$logx:methodology,
	$logx:references
);

declare function logx:descendants-of-type($ancestor,$type){
	$ancestor//text()[logx:gettype(.)=$type]
};

declare function logx:hascontent($items as node()*){
	normalize-space(string($items)) != ''
};

(: Retrieves (preceding) heading name given a content node :)
declare function logx:gettype($content){
	if($content/parent::h1) then
		$logx:title
	else
		normalize-space(string-join($content/(preceding::h2[1])/text(),""))
};

(:declare function logx:filterbytype($nodes,$type){
	$nodes[not(self::h2)][not(self::br)][preceding::h2[1]//text()[contains(.,$type)]][not(normalize-space(string(.))='')]
};:)

declare function logx:paperid($node){
	replace(base-uri(logx:paperroot($node)),".*/([^/]+)\.[^/]+$", "$1")
};

declare function logx:papertitle($node){
	logx:paperroot($node)//h1/string(.)
};

declare function logx:paperroot($node){
	typeswitch($node)
		case document-node() return $node
		default return root($node)
};

declare function logx:aggregate($filepaths as xs:string){
    for $token in tokenize($filepaths, ',') return doc(resolve-uri($token))
};

declare function logx:editor-link($node){
	logx:editor-link($node, $node//text())
};

declare function logx:editor-link($node, $text){
	{$text}
};

declare function logx:viewer-link($path, $nodes){
	{$nodes}
};

(: Returns all the document nodes of the XHTML note files :)
declare function logx:menu(){
	for $item in (
		logx:viewer-link('xq/index.xq','Home'),
		logx:viewer-link('xq/tasks.xq','Tasks'),
		logx:viewer-link('xq/headers.xq','Browse')
	)
	return ($item,' ')
};

(: templates a webpage, including the nodes specified :)
declare function logx:webpage($nodes){

		    <meta content="text/html; charset=utf-16" http-equiv="content-type"></meta>
			<link href="/style.css" rel="stylesheet" type="text/css"></link>

						{logx:menu()}

						<form action="/search.xq">

									<input type="text" name="text" />
									<input type="submit" value="Search"/>

						</form>

								{$nodes}

};

module namespace logx="http://cefn.com/logx";

declare default element namespace "http://www.w3.org/1999/xhtml";

declare variable $logx:sourceurls as xs:string external;

declare variable $logx:collection := logx:aggregate($logx:sourceurls);

declare function logx:aggregate($filepaths as xs:string){
    for $token in tokenize($filepaths, ',') return doc(resolve-uri($token))
};

declare function logx:editor-link($node){
	logx:editor-link($node, $node//text())
};

declare function logx:editor-link($node, $text){
	{$text}
};

declare function logx:viewer-link($path, $nodes){
	{$nodes}
};

(: Returns all the document nodes of the XHTML note files :)
declare function logx:menu(){
	for $item in (
		logx:viewer-link('xq/index.xq','Home'),
		logx:viewer-link('xq/tasks.xq','Tasks'),
		logx:viewer-link('xq/headers.xq','Browse')
	)
	return ($item,' ')
};

(: templates a webpage, including the nodes specified :)
declare function logx:webpage($nodes){

		    <meta content="text/html; charset=utf-16" http-equiv="content-type"></meta>
			<link href="/style.css" rel="stylesheet" type="text/css"></link>

						{logx:menu()}

						<form action="/search.xq">

									<input type="text" name="text" />
									<input type="submit" value="Search"/>

						</form>

								{$nodes}

};


[bugfix] Correct XML:DB URI

[bugfix] Correct XML:DB URI

(:
 : 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 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:assertXPath("contains($result, 'null')")
function ser:exist-json-ignore-whitespace-text-nodes-false() {
      let $node := <book>
          <author>John Doe</author>
          <author>Robert Smith</author>
          <author>  </author>
      </book>
    return fn:serialize($node, map {"method":"json", "media-type":"application/json", xs:QName("exist:json-ignore-whitespace-text-nodes"): false()})
};

declare
    %test:assertXPath("contains($result, 'true')")
function ser:exist-json-ignore-whitespace-text-nodes-true() {
    let $node :=

                stuff

    return fn:serialize($node, map {"method":"json", "media-type":"application/json", xs:QName("exist:json-ignore-whitespace-text-nodes"): false()})
};

declare
    %test:assertXPath("contains($result, 'true')")
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()})
};

(:
 : 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 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:assertXPath("contains($result, 'null')")
function ser:exist-json-ignore-whitespace-text-nodes-false() {
      let $node := <book>
          <author>John Doe</author>
          <author>Robert Smith</author>
          <author>  </author>
      </book>
    return fn:serialize($node, map {"method":"json", "media-type":"application/json", xs:QName("exist:json-ignore-whitespace-text-nodes"): false()})
};

declare
    %test:assertXPath("contains($result, 'true')")
function ser:exist-json-ignore-whitespace-text-nodes-true() {
    let $node :=

                stuff

    return fn:serialize($node, map {"method":"json", "media-type":"application/json", xs:QName("exist:json-ignore-whitespace-text-nodes"): false()})
};

declare
    %test:assertXPath("contains($result, 'true')")
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()})
};


Update BaseX XQuery module

Update BaseX XQuery module

xquery version "3.1";
(:~
 : BaseX XQuery Module functions
 :
 : @see http://docs.basex.org/wiki/XQuery_Module
 :)
module namespace xquery = "http://basex.org/modules/xquery";

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

declare option o:requires "basex/7.3";

declare %a:since("basex", "7.3") function xquery:eval($query as xs:string) as item()* external;
declare %a:since("basex", "7.3") function xquery:eval($query as xs:string, $bindings as map(*)?) as item()* external;
declare %a:since("basex", "7.8.2") function xquery:eval($query as xs:string, $bindings as map(*)?, $options as map(*)?) as item()* external;
declare %a:since("basex", "7.3") function xquery:eval-update($query as xs:string) as item()* external;
declare %a:since("basex", "7.3") function xquery:eval-update($query as xs:string, $bindings as map(*)?) as item()* external;
declare %a:since("basex", "7.8.2") function xquery:eval-update($query as xs:string, $bindings as map(*)?, $options as map(*)?) as item() external;
declare %a:since("basex", "7.3") %a:until("basex", "9.2", "xquery:eval") function xquery:invoke($uri as xs:string) as item()* external;
declare %a:since("basex", "7.3") %a:until("basex", "9.2", "xquery:eval") function xquery:invoke($uri as xs:string, $bindings as map(*)?) as item()* external;
declare %a:since("basex", "7.3") %a:until("basex", "9.2", "xquery:eval") function xquery:invoke($uri as xs:string, $bindings as map(*)?, $options as map(*)?) as item()* external;
declare %a:since("basex", "9.0") %a:until("basex", "9.2", "xquery:eval-update") function xquery:invoke-update($uri as xs:string) as item()* external;
declare %a:since("basex", "9.0") %a:until("basex", "9.2", "xquery:eval-update") function xquery:invoke-update($uri as xs:string, $bindings as map(*)?) as item()* external;
declare %a:since("basex", "9.0") %a:until("basex", "9.2", "xquery:eval-update") function xquery:invoke-update($uri as xs:string, $bindings as map(*)?, $options as map(*)?) as item()* external;
declare %a:since("basex", "8.0") function xquery:parse($query as xs:string) as item()? external;
declare %a:since("basex", "8.0") function xquery:parse($query as xs:string, $options as map(*)?) as item()? external;
declare %a:since("basex", "7.3") function xquery:parse-uri($uri as xs:string) as item()? external;
declare %a:since("basex", "7.3") function xquery:parse-uri($uri as xs:string, $options as map(*)?) as item()? external;
declare %a:since("basex", "8.5") function xquery:fork-join($functions as function(*)*) as item()* external;
declare %a:since("basex", "7.8") %a:until("basex", "8.0") function xquery:evaluate() as item()* external;
declare %a:since("basex", "7.3") %a:until("basex", "8.5") %a:see-also("basex", "8.5", "prof:type") function xquery:type() as item()* external;
declare %a:since("basex", "8.0") %a:until("basex", "9.0") %a:see-also("basex", "9.0", "xquery:eval-update") function xquery:update() as item()* external;

xquery version "3.1";
(:~
 : BaseX XQuery Module functions
 :
 : @see http://docs.basex.org/wiki/XQuery_Module
 :)
module namespace xquery = "http://basex.org/modules/xquery";

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

declare option o:requires "basex/7.3";

declare %a:since("basex", "7.3") function xquery:eval($query as xs:string) as item()* external;
declare %a:since("basex", "7.3") function xquery:eval($query as xs:string, $bindings as map(*)?) as item()* external;
declare %a:since("basex", "7.8.2") function xquery:eval($query as xs:string, $bindings as map(*)?, $options as map(*)?) as item()* external;
declare %a:since("basex", "7.3") function xquery:eval-update($query as xs:string) as item()* external;
declare %a:since("basex", "7.3") function xquery:eval-update($query as xs:string, $bindings as map(*)?) as item()* external;
declare %a:since("basex", "7.8.2") function xquery:eval-update($query as xs:string, $bindings as map(*)?, $options as map(*)?) as item() external;
declare %a:since("basex", "7.3") function xquery:invoke($uri as xs:string) as item()* external;
declare %a:since("basex", "7.3") function xquery:invoke($uri as xs:string, $bindings as map(*)?) as item()* external;
declare %a:since("basex", "7.3") function xquery:invoke($uri as xs:string, $bindings as map(*)?, $options as map(*)?) as item()* external;
declare %a:since("basex", "9.0") function xquery:invoke-update($uri as xs:string) as item()* external;
declare %a:since("basex", "9.0") function xquery:invoke-update($uri as xs:string, $bindings as map(*)?) as item()* external;
declare %a:since("basex", "9.0") function xquery:invoke-update($uri as xs:string, $bindings as map(*)?, $options as map(*)?) as item()* external;
declare %a:since("basex", "8.0") function xquery:parse($query as xs:string) as item()? external;
declare %a:since("basex", "8.0") function xquery:parse($query as xs:string, $options as map(*)?) as item()? external;
declare %a:since("basex", "7.3") function xquery:parse-uri($uri as xs:string) as item()? external;
declare %a:since("basex", "7.3") function xquery:parse-uri($uri as xs:string, $options as map(*)?) as item()? external;
declare %a:since("basex", "8.5") function xquery:fork-join($functions as function(*)*) as item()* external;
declare %a:since("basex", "7.8") %a:until("basex", "8.0") function xquery:evaluate() as item()* external;
declare %a:since("basex", "7.3") %a:until("basex", "8.5") %a:see-also("basex", "8.5", "prof:type") function xquery:type() as item()* external;
declare %a:since("basex", "8.0") %a:until("basex", "9.0") %a:see-also("basex", "9.0", "xquery:eval-update") function xquery:update() as item()* external;


[apps mods] fixed a bug in the style module CSS import

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

xquery version "1.0";

module namespace style = "http://exist-db.org/mods-style";

declare namespace request="http://exist-db.org/xquery/request";
declare namespace xf="http://www.w3.org/2002/xforms";
declare namespace xrx="http://code.google.com/p/xrx";

declare variable $style:context := request:get-context-path();
declare variable $style:site-home := '/';
declare variable $style:web-path-to-site := '/db/org/library';
declare variable $style:web-path-to-app := style:substring-before-last-slash(style:substring-before-last-slash(substring-after(request:get-uri(), '/rest')));
declare variable $style:db-path-to-site  := concat('xmldb:exist://',  $style:web-path-to-site);
declare variable $style:db-path-to-app  := concat('xmldb:exist://', $style:web-path-to-app) ;
declare variable $style:db-path-to-app-data := concat($style:db-path-to-app, '/data');

declare variable $style:site-resources := concat(request:get-context-path(), '/rest', $style:web-path-to-site, '/resources');
declare variable $style:site-images := concat($style:site-resources, '/images');
declare variable $style:site-css := concat($style:site-resources, '/css');
declare variable $style:site-info-file := concat($style:web-path-to-site, '/site-info.xml');
declare variable $style:site-info := doc($style:site-info-file);
declare variable $style:form-debug-default := true();

declare function style:substring-before-last-slash($arg as xs:string?)  as xs:string {

   if (matches($arg, '/'))
   then replace($arg,
            concat('^(.*)', '/','.*'),
            '$1')
   else ''
 } ;

declare function style:assemble-page($title as xs:string*, $breadcrumbs as node()*,
                                     $style as element()*, $content as node()+)
as element() {
    (
    util:declare-option('exist:serialize', 'method=xhtml media-type=text/html indent=yes')
    ,

            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <title>{ $title }</title>
            { style:css('xhtml') }
            { $style }

                { style:header() }
                { $breadcrumbs }

{$title}

                   { $content }

                { style:footer() }

     )
};

declare function style:assemble-page($title as xs:string, $content as node()+)
as element() {
    style:assemble-page($title, style:breadcrumbs(), (), $content)
};

declare function style:assemble-page($title as xs:string, $style as node(), $content as node()+)
as element() {
    style:assemble-page($title, style:breadcrumbs(), $style, $content)
};

declare function style:breadcrumbs() as node() {

      Library Home >
      Library Apps >
      MODS Editor

};

declare function style:assemble-form($model as node(), $content as node()+)
as node()+ {
    style:assemble-form((), (), $model, $content, true())
};

(:~
    An alternate version of style:assemble-form(), allowing debug mode.

    @param $model an XForms model node
    @param $content nodes for the body of the page
    @param $debug boolean to activate XSLTForms debug mode
    @return properly serialized XHTML+XForms page
:)
declare function style:assemble-form($model as node(), $content as node()+, $debug as xs:boolean)
as node()+ {
    style:assemble-form((), (), $model, $content, $debug)
};

(:~
    A helper function for style:assemble-form(), with all optional parameters.

    @param $dummy-attributes an optional sequence of attributes to add to the HTML element
    @param $style an optional style node containing CDATA-encased CSS definitions
    @param $model an XForms model node
    @param $content nodes for the body of the page
    @return properly serialized XHTML+XForms page
:)
declare function style:assemble-form($title as xs:string, $dummy-attributes as attribute()*, $style as element(style)*,
                                     $model as element(xf:model), $content as node()+)
as node()+ {
    style:assemble-form($dummy-attributes, $style, $model, $content, $style:form-debug-default)
};

(:~
    A helper function for style:assemble-form(), with all optional parameters.

    @param $title the text node containing the title of the page
    @param $breadcrumbs the element node containing the breadcrumbs
    @param $style an optional style node containing CDATA-encased CSS definitions
    @param $model an XForms model node
    @param $content nodes for the body of the page
    @param $dummy-attributes an optional sequence of attributes to add to the HTML element
    @param $debug boolean to activate XSLTForms debug mode
    @return properly serialized XHTML+XForms page
:)
declare function style:assemble-form(
        $title as xs:string,
        $dummy-attributes as attribute()*,
        $style as node()*,
        $model as node(),
        $content as node()+,
        $debug as xs:boolean)
as node()+ {
    util:declare-option('exist:serialize', 'method=xhtml media-type=text/xml indent=yes process-xsl-pi=no')
    ,
    processing-instruction xml-stylesheet {concat('type="text/xsl" href="', request:get-context-path(), '/rest', '/db/xforms/xsltforms/xsltforms.xsl"')}
    ,
    if ($debug) then
        processing-instruction xsltforms-options {'debug="yes"'}
    else ()
    ,
    { $dummy-attributes }

            <title>{ $title }</title>
            <link rel="stylesheet" type="text/css" href="edit.css"/>
            { style:css('xforms') }
            { $style }
            { $model }

                { style:header() }

{$title}

                    { $content }

                { style:footer() }

};

declare function style:css($page-type as xs:string)
as node()+ {
    if ($page-type eq 'xhtml') then
        (

        <link rel="stylesheet" href="{$style:site-css}/blueprint/screen.css" type="text/css" media="screen, projection" />,
        <link rel="stylesheet" href="{$style:site-css}/blueprint/print.css" type="text/css" media="print" />,,
        <link rel="stylesheet" href="{$style:site-css}/style.css" type="text/css" media="screen, projection" />

    )
    else if ($page-type eq 'xforms') then
        <link rel="stylesheet" href="{$style:site-css}/xforms.css.xq" type="text/css" />
    else ()
};

declare function style:header() as node()+  {

            Demo of MODS Editor

};

declare function style:footer()
as node()*  {
    let $footer-message := $style:site-info//xrx:site-footer-message/node()
    return

                    Demo of MODS Editor

};

xquery version "1.0";

module namespace style = "http://exist-db.org/mods-style";

declare namespace request="http://exist-db.org/xquery/request";
declare namespace xf="http://www.w3.org/2002/xforms";
declare namespace xrx="http://code.google.com/p/xrx";

declare variable $style:context := request:get-context-path();
declare variable $style:site-home := '/';
declare variable $style:web-path-to-site := '/db/org/library';
declare variable $style:web-path-to-app := style:substring-before-last-slash(style:substring-before-last-slash(substring-after(request:get-uri(), '/rest')));
declare variable $style:db-path-to-site  := concat('xmldb:exist://',  $style:web-path-to-site);
declare variable $style:db-path-to-app  := concat('xmldb:exist://', $style:web-path-to-app) ;
declare variable $style:db-path-to-app-data := concat($style:db-path-to-app, '/data');

declare variable $style:site-resources := concat(request:get-context-path(), '/rest', $style:web-path-to-site, '/resources');
declare variable $style:site-images := concat($style:site-resources, '/images');
declare variable $style:site-css := concat($style:site-resources, '/css');
declare variable $style:site-info-file := concat($style:web-path-to-site, '/site-info.xml');
declare variable $style:site-info := doc($style:site-info-file);
declare variable $style:form-debug-default := true();

declare function style:substring-before-last-slash($arg as xs:string?)  as xs:string {

   if (matches($arg, '/'))
   then replace($arg,
            concat('^(.*)', '/','.*'),
            '$1')
   else ''
 } ;

declare function style:assemble-page($title as xs:string*, $breadcrumbs as node()*,
                                     $style as element()*, $content as node()+)
as element() {
    (
    util:declare-option('exist:serialize', 'method=xhtml media-type=text/html indent=yes')
    ,

            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
            <title>{ $title }</title>
            { style:css('xhtml') }
            { $style }

                { style:header() }
                { $breadcrumbs }

{$title}

                   { $content }

                { style:footer() }

     )
};

declare function style:assemble-page($title as xs:string, $content as node()+)
as element() {
    style:assemble-page($title, style:breadcrumbs(), (), $content)
};

declare function style:assemble-page($title as xs:string, $style as node(), $content as node()+)
as element() {
    style:assemble-page($title, style:breadcrumbs(), $style, $content)
};

declare function style:breadcrumbs() as node() {

      Library Home >
      Library Apps >
      MODS Editor

};

declare function style:assemble-form($model as node(), $content as node()+)
as node()+ {
    style:assemble-form((), (), $model, $content, true())
};

(:~
    An alternate version of style:assemble-form(), allowing debug mode.

    @param $model an XForms model node
    @param $content nodes for the body of the page
    @param $debug boolean to activate XSLTForms debug mode
    @return properly serialized XHTML+XForms page
:)
declare function style:assemble-form($model as node(), $content as node()+, $debug as xs:boolean)
as node()+ {
    style:assemble-form((), (), $model, $content, $debug)
};

(:~
    A helper function for style:assemble-form(), with all optional parameters.

    @param $dummy-attributes an optional sequence of attributes to add to the HTML element
    @param $style an optional style node containing CDATA-encased CSS definitions
    @param $model an XForms model node
    @param $content nodes for the body of the page
    @return properly serialized XHTML+XForms page
:)
declare function style:assemble-form($title as xs:string, $dummy-attributes as attribute()*, $style as element(style)*,
                                     $model as element(xf:model), $content as node()+)
as node()+ {
    style:assemble-form($dummy-attributes, $style, $model, $content, $style:form-debug-default)
};

(:~
    A helper function for style:assemble-form(), with all optional parameters.

    @param $title the text node containing the title of the page
    @param $breadcrumbs the element node containing the breadcrumbs
    @param $style an optional style node containing CDATA-encased CSS definitions
    @param $model an XForms model node
    @param $content nodes for the body of the page
    @param $dummy-attributes an optional sequence of attributes to add to the HTML element
    @param $debug boolean to activate XSLTForms debug mode
    @return properly serialized XHTML+XForms page
:)
declare function style:assemble-form(
        $title as xs:string,
        $dummy-attributes as attribute()*,
        $style as node()*,
        $model as node(),
        $content as node()+,
        $debug as xs:boolean)
as node()+ {
    util:declare-option('exist:serialize', 'method=xhtml media-type=text/xml indent=yes process-xsl-pi=no')
    ,
    processing-instruction xml-stylesheet {concat('type="text/xsl" href="', request:get-context-path(), '/rest', '/db/xforms/xsltforms/xsltforms.xsl"')}
    ,
    if ($debug) then
        processing-instruction xsltforms-options {'debug="yes"'}
    else ()
    ,
    { $dummy-attributes }

            <title>{ $title }</title>
            <link rel="stylesheet" type="text/css" href="edit.css"/>
            { style:css('xforms') }
            { $style }
            { $model }

                { style:header() }

{$title}

                    { $content }

                { style:footer() }

};

declare function style:css($page-type as xs:string)
as node()+ {
    if ($page-type eq 'xhtml') then
        (

        <link rel="stylesheet" href="{$style:site-css}/blueprint/screen.css" type="text/css" media="screen, projection" />,
        <link rel="stylesheet" href="{$style:site-css}/blueprint/print.css" type="text/css" media="print" />,,
        <link rel="stylesheet" href="{$style:site-css}/styles.css" type="text/css" media="screen, projection" />

    )
    else if ($page-type eq 'xforms') then
        <link rel="stylesheet" href="{$style:site-css}/xforms.css.xq" type="text/css" />
    else ()
};

declare function style:header() as node()+  {

            Demo of MODS Editor

};

declare function style:footer()
as node()*  {
    let $footer-message := $style:site-info//xrx:site-footer-message/node()
    return

                    Demo of MODS Editor

};