add labels to the form and a 'none' option

xquery version "3.0";
declare namespace tei = "http://www.tei-c.org/ns/1.0";
let $authors := doc('/db/VTLGP/ancillary/corpus-autores.xml')//tei:person[@xml:id/string() = collection('/db/VTLGP/edition')//tei:name[@role eq 'author']/substring(@ref, 2)]
let $periods := $authors/tei:floruit/@period
let $copyists := collection('/db/VTLGP/edition')//tei:div//tei:title//tei:rdg/substring(@hand, 2)
return
    (<form
        method="GET"
        action="edition.php">
        {
            for $i in 1 to (count($authors))
            let $author := $authors[$i]
            let $songs := collection('/db/VTLGP/edition')//tei:name[@role eq 'author'][substring(@ref, 2) = $author/string(@xml:id)]/ancestor::tei:div
            order by $author
            return
                <fieldset>
                    <legend>{$author/tei:persName/string()}</legend>

                        <input
                            type="radio"
                            name="author[{$i}]"
                            class="all"
                            id="none1"
                            checked="checked"/>
                        None
                            Nenhuma
                        <input
                            type="radio"
                            name="author[{$i}]"
                            value="{$author/@xml:id}"
                            id="author{$i}"
                            class="all"/>
                        Todas
                            All
                        <input
                            type="radio"
                            name="author[{$i}]"
                            class="show"
                            id="select{$i}"/>
                        Seleccionar
                            Select

                            {
                                for $song in $songs
                                order by $song/substring(@corresp, 2)
                                return

<input
                                            type="checkbox"
                                            id="{$song/substring(@corresp, 2)}"
                                            name="song[]"
                                            value="{$song/substring(@corresp, 2)}"/>
                                        {string-join($song//tei:title//tei:idno, ', ')}

                            }

                </fieldset>
        }
        <button
            class="submit"
            type="submit">PesquisaSearch</button>
    </form>,

Por períodoBy period
,
    <form
        method="GET"
        action="edition.php">
        {
            for $period in distinct-values($periods)
            let $songs := collection('/db/VTLGP/edition')//tei:name[@role eq 'author'][substring(@ref, 2) = $authors[tei:floruit/@period eq $period]/@xml:id]/ancestor::tei:div
            order by number($period)
            return
                <fieldset>
                    <legend>Período {$period}Period {$period}</legend>

                        <input
                            type="radio"
                            name="period[{$period}]"
                            class="all"
                            id="none2"
                            checked="checked"/>
                        None
                            Nenhuma
                        <input
                            type="radio"
                            name="period[{$period}]"
                            value="{$period}"
                            id="{$period}"
                            class="all"/>
                        Todas
                            All
                        <input
                            type="radio"
                            name="period[{$period}]"
                            id="select{$period}"
                            class="show"/>
                        Seleccionar
                            Select

                            {
                                for $song in $songs
                                order by $song/substring(@corresp, 2)
                                return

<input
                                            type="checkbox"
                                            id="{$song/substring(@corresp, 2)}"
                                            name="song[]"
                                            value="{$song/substring(@corresp, 2)}"/>
                                        {string-join($song//tei:title//tei:idno, ', ')}

                            }

                </fieldset>
        }
        <button
            class="submit"
            type="submit">PesquisaSearch</button>
    </form>,

Por copistaBy scribe
,
    <form
        method="GET"
        action="edition.php">
        {
            for $hand in distinct-values($copyists)
            let $songs := collection('/db/VTLGP/edition')//tei:div[@type eq 'poem'][.//tei:title//tei:rdg/substring(@hand, 2) = $hand]
            order by $hand
            return
                <fieldset>
                    <legend>Copista {$hand} (manuscrito{
                                (if ($hand = ('b', 'c', 'a', 'd', 'e')) then
                                    ' B'
                                else
                                    (if ($hand = 'v') then
                                        ' V'
                                    else
                                        ' A'))
                            })
                        Scribe {$hand} (witness{
                                (if ($hand = ('b', 'c', 'a', 'd', 'e')) then
                                    ' B'
                                else
                                    (if ($hand = 'v') then
                                        ' V'
                                    else
                                        ' A'))
                            })</legend>

                        <input
                            type="radio"
                            name="scribe[{$hand}]"
                            class="all"
                            id="none3"
                            checked="checked"/>
                        None
                            Nenhuma
                        <input
                            type="radio"
                            name="scribe[{$hand}]"
                            value="{$hand}"
                            id="{$hand}"
                            class="all"/>
                        Todas
                            All
                        <input
                            type="radio"
                            name="scribe[{$hand}]"
                            class="show"
                            id="select{$hand}"/>
                        Seleccionar
                            Select

                            {
                                for $song in $songs
                                order by $song/substring(@corresp, 2)
                                return

<input
                                            type="checkbox"
                                            id="{$song/substring(@corresp, 2)}"
                                            name="song[]"
                                            value="{$song/substring(@corresp, 2)}"/>
                                        {string-join($song//tei:title//tei:idno, ', ')}

                            }

                </fieldset>
        }
        <button
            class="submit"
            type="submit">PesquisaSearch</button>
    </form>
    )

xquery version "3.0";
declare namespace tei = "http://www.tei-c.org/ns/1.0";
let $authors := doc('/db/VTLGP/ancillary/corpus-autores.xml')//tei:person[@xml:id/string() = collection('/db/VTLGP/edition')//tei:name[@role eq 'author']/substring(@ref, 2)]
let $periods := $authors/tei:floruit/@period
let $copyists := collection('/db/VTLGP/edition')//tei:div//tei:title//tei:rdg/substring(@hand, 2)
return
    (<form
        method="GET"
        action="edition.php">
        {
            for $i in 1 to (count($authors))
            let $author := $authors[$i]
            let $songs := collection('/db/VTLGP/edition')//tei:name[@role eq 'author'][substring(@ref, 2) = $author/string(@xml:id)]/ancestor::tei:div
            order by $author
            return
                <fieldset>
                    <legend>{$author/tei:persName/string()}</legend>

                        <input
                            type="radio"
                            name="author[{$i}]"
                            value="{$author/@xml:id}"
                            class="all"/>
                        Todas
                        All
                        <input
                            type="radio"
                            name="author[{$i}]"
                            class="show"/>
                        Seleccionar
                        Select

                            {
                                for $song in $songs
                                return

<input
                                            type="checkbox"
                                            name="song[]"
                                            value="{$song/substring(@corresp, 2)}"/>
                                        {string-join($song//tei:title//tei:idno, ', ')}

                            }

                </fieldset>
        }
        <button
            class="submit"
            type="submit">PesquisaSearch</button>
    </form>,

Por períodoBy period
,
    <form
        method="GET"
        action="edition.php">
        {
            for $period in distinct-values($periods)
            let $songs := collection('/db/VTLGP/edition')//tei:name[@role eq 'author'][substring(@ref, 2) = $authors[tei:floruit/@period eq $period]/@xml:id]/ancestor::tei:div
            order by number($period)
            return
                <fieldset>
                    <legend>Período {$period}Period {$period}</legend>

                        <input
                            type="radio"
                            name="period[{$period}]"
                            value="{$period}"
                            class="all"/>
                        Todas
                        All
                        <input
                            type="radio"
                            name="period[{$period}]"
                            class="show"/>
                        Seleccionar
                        Select

                            {
                                for $song in $songs
                                return

<input
                                            type="checkbox"
                                            name="song[]"
                                            value="{$song/substring(@corresp, 2)}"/>
                                        {string-join($song//tei:title//tei:idno, ', ')}

                            }

                </fieldset>
        }
        <button
            class="submit"
            type="submit">PesquisaSearch</button>
    </form>,

CopistaScribe
,
    <form
        method="GET"
        action="edition.php">
        {
            for $hand in distinct-values($copyists)
            let $songs := collection('/db/VTLGP/edition')//tei:div[@type eq 'poem'][.//tei:title//tei:rdg/substring(@hand, 2) = $hand]
            order by $hand
            return
                <fieldset>
                    <legend>Copista {$hand} (manuscrito{
                                (if ($hand = ('b', 'c', 'a', 'd', 'e')) then
                                    ' B'
                                else
                                    (if ($hand = 'v') then
                                        ' V'
                                    else
                                        ' A'))
                            })
                        Scribe {$hand} (witness{
                                (if ($hand = ('b', 'c', 'a', 'd', 'e')) then
                                    ' B'
                                else
                                    (if ($hand = 'v') then
                                        ' V'
                                    else
                                        ' A'))
                            })</legend>

                        <input
                            type="radio"
                            name="scribe[{$hand}]"
                            value="{$hand}"
                            class="all"/>
                        Todas
                        All
                        <input
                            type="radio"
                            name="scribe[{$hand}]"
                            class="show"/>
                        Seleccionar
                        Select

                            {
                                for $song in $songs
                                return

<input
                                            type="checkbox"
                                            name="song[]"
                                            value="{$song/substring(@corresp, 2)}"/>
                                        {string-join($song//tei:title//tei:idno, ', ')}

                            }

                </fieldset>
        }
        <button
            class="submit"
            type="submit">PesquisaSearch</button>
    </form>
    )


Update `since` annotation to appropriate BaseX version.

xquery version "3.0";
(:~
: BaseX binary module functions
:
:)
module namespace bin = "http://expath.org/ns/binary";

import module namespace a = "http://reecedunn.co.uk/xquery/annotations" at "res://reecedunn.co.uk/xquery/annotations.xqy";

declare %a:since("basex", "7.8") function bin:hex($in as xs:string?) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:bin($in as xs:string?) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:octal($in as xs:string?) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:to-octets($in as xs:base64Binary) as xs:integer* external;
declare %a:since("basex", "7.8") function bin:from-octets($in as xs:integer*) as xs:base64Binary external;
declare %a:since("basex", "7.8") function bin:length($in as xs:base64Binary) as xs:integer external;
declare %a:since("basex", "7.8") function bin:part($in as xs:base64Binary?, $offset as xs:integer) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:part($in as xs:base64Binary?, $offset as xs:integer, $size as xs:integer) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:join($in as xs:base64Binary*) as xs:base64Binary external;
declare %a:since("basex", "7.8") function bin:insert-before($in as xs:base64Binary?, $offset as xs:integer, $extra as xs:base64Binary?) as xs:base64Binary external;
declare %a:since("basex", "7.8") function bin:pad-left($in as xs:base64Binary?, $size as xs:integer) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:pad-left($in as xs:base64Binary?, $size as xs:integer, $octect as xs:integer) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:pad-right($in as xs:base64Binary?, $size as xs:integer) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:pad-right($in as xs:base64Binary?, $size as xs:integer, $octect as xs:integer) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:find($in as xs:base64Binary?, $offset as xs:integer, $search as xs:base64Binary) as xs:integer? external;
declare %a:since("basex", "7.8") function bin:decode-string($in as xs:base64Binary?, $encoding as xs:string) as xs:string? external;
declare %a:since("basex", "7.8") function bin:decode-string($in as xs:base64Binary?, $encoding as xs:string, $offset as xs:integer) as xs:string? external;
declare %a:since("basex", "7.8") function bin:decode-string($in as xs:base64Binary?, $encoding as xs:string, $offset as xs:integer, $size as xs:integer) as xs:string? external;
declare %a:since("basex", "7.8") function bin:encode-string($in as xs:string?, $encoding as xs:string) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:pack-double($in as xs:double) as xs:base64Binary external;
declare %a:since("basex", "7.8") function bin:pack-double($in as xs:double, $octet-order as xs:string) as xs:base64Binary external;
declare %a:since("basex", "7.8") function bin:pack-float($in as xs:float) as xs:base64Binary external;
declare %a:since("basex", "7.8") function bin:pack-float($in as xs:float, $octet-order as xs:string) as xs:base64Binary external;
declare %a:since("basex", "7.8") function bin:pack-integer($in as xs:integer, $size as xs:integer) as xs:base64Binary external;
declare %a:since("basex", "7.8") function bin:pack-integer($in as xs:integer, $size as xs:integer, $octet-order as xs:string) as xs:base64Binary external;
declare %a:since("basex", "7.8") function bin:unpack-double($in as xs:base64Binary, $offset as xs:integer) as xs:double external;
declare %a:since("basex", "7.8") function bin:unpack-double($in as xs:base64Binary, $offset as xs:integer, $octet-order as xs:string) as xs:double external;
declare %a:since("basex", "7.8") function bin:unpack-float($in as xs:base64Binary, $offset as xs:integer) as xs:float external;
declare %a:since("basex", "7.8") function bin:unpack-float($in as xs:base64Binary, $offset as xs:integer, $octet-order as xs:string) as xs:float external;
declare %a:since("basex", "7.8") function bin:unpack-integer($in as xs:base64Binary, $offset as xs:integer, $size as xs:integer) as xs:integer external;
declare %a:since("basex", "7.8") function bin:unpack-integer($in as xs:base64Binary, $offset as xs:integer, $size as xs:integer, $octet-order as xs:string) as xs:integer external;
declare %a:since("basex", "7.8") function bin:unpack-unsigned-integer($in as xs:base64Binary, $offset as xs:integer, $size as xs:integer) as xs:integer external;
declare %a:since("basex", "7.8") function bin:unpack-unsigned-integer($in as xs:base64Binary, $offset as xs:integer, $size as xs:integer, $octet-order as xs:string) as xs:integer external;
declare %a:since("basex", "7.8") function bin:or($a as xs:base64Binary?, $b as xs:base64Binary?) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:xor($a as xs:base64Binary?, $b as xs:base64Binary?) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:and($a as xs:base64Binary?, $b as xs:base64Binary?) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:not($in as xs:base64Binary?) as xs:base64Binary? external;
declare %a:since("basex", "7.8") function bin:shift($in as xs:base64Binary?, $by as xs:integer) as xs:base64Binary? external;

xquery version "3.0";
(:~
: BaseX binary module functions
:
:)
module namespace bin = "http://expath.org/ns/binary";

import module namespace a = "http://reecedunn.co.uk/xquery/annotations" at "res://reecedunn.co.uk/xquery/annotations.xqy";

declare %a:since("basex", "9.0") function bin:hex($in as xs:string?) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:bin($in as xs:string?) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:octal($in as xs:string?) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:to-octets($in as xs:base64Binary) as xs:integer* external;
declare %a:since("basex", "9.0") function bin:from-octets($in as xs:integer*) as xs:base64Binary external;
declare %a:since("basex", "9.0") function bin:length($in as xs:base64Binary) as xs:integer external;
declare %a:since("basex", "9.0") function bin:part($in as xs:base64Binary?, $offset as xs:integer) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:part($in as xs:base64Binary?, $offset as xs:integer, $size as xs:integer) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:join($in as xs:base64Binary*) as xs:base64Binary external;
declare %a:since("basex", "9.0") function bin:insert-before($in as xs:base64Binary?, $offset as xs:integer, $extra as xs:base64Binary?) as xs:base64Binary external;
declare %a:since("basex", "9.0") function bin:pad-left($in as xs:base64Binary?, $size as xs:integer) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:pad-left($in as xs:base64Binary?, $size as xs:integer, $octect as xs:integer) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:pad-right($in as xs:base64Binary?, $size as xs:integer) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:pad-right($in as xs:base64Binary?, $size as xs:integer, $octect as xs:integer) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:find($in as xs:base64Binary?, $offset as xs:integer, $search as xs:base64Binary) as xs:integer? external;
declare %a:since("basex", "9.0") function bin:decode-string($in as xs:base64Binary?, $encoding as xs:string) as xs:string? external;
declare %a:since("basex", "9.0") function bin:decode-string($in as xs:base64Binary?, $encoding as xs:string, $offset as xs:integer) as xs:string? external;
declare %a:since("basex", "9.0") function bin:decode-string($in as xs:base64Binary?, $encoding as xs:string, $offset as xs:integer, $size as xs:integer) as xs:string? external;
declare %a:since("basex", "9.0") function bin:encode-string($in as xs:string?, $encoding as xs:string) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:pack-double($in as xs:double) as xs:base64Binary external;
declare %a:since("basex", "9.0") function bin:pack-double($in as xs:double, $octet-order as xs:string) as xs:base64Binary external;
declare %a:since("basex", "9.0") function bin:pack-float($in as xs:float) as xs:base64Binary external;
declare %a:since("basex", "9.0") function bin:pack-float($in as xs:float, $octet-order as xs:string) as xs:base64Binary external;
declare %a:since("basex", "9.0") function bin:pack-integer($in as xs:integer, $size as xs:integer) as xs:base64Binary external;
declare %a:since("basex", "9.0") function bin:pack-integer($in as xs:integer, $size as xs:integer, $octet-order as xs:string) as xs:base64Binary external;
declare %a:since("basex", "9.0") function bin:unpack-double($in as xs:base64Binary, $offset as xs:integer) as xs:double external;
declare %a:since("basex", "9.0") function bin:unpack-double($in as xs:base64Binary, $offset as xs:integer, $octet-order as xs:string) as xs:double external;
declare %a:since("basex", "9.0") function bin:unpack-float($in as xs:base64Binary, $offset as xs:integer) as xs:float external;
declare %a:since("basex", "9.0") function bin:unpack-float($in as xs:base64Binary, $offset as xs:integer, $octet-order as xs:string) as xs:float external;
declare %a:since("basex", "9.0") function bin:unpack-integer($in as xs:base64Binary, $offset as xs:integer, $size as xs:integer) as xs:integer external;
declare %a:since("basex", "9.0") function bin:unpack-integer($in as xs:base64Binary, $offset as xs:integer, $size as xs:integer, $octet-order as xs:string) as xs:integer external;
declare %a:since("basex", "9.0") function bin:unpack-unsigned-integer($in as xs:base64Binary, $offset as xs:integer, $size as xs:integer) as xs:integer external;
declare %a:since("basex", "9.0") function bin:unpack-unsigned-integer($in as xs:base64Binary, $offset as xs:integer, $size as xs:integer, $octet-order as xs:string) as xs:integer external;
declare %a:since("basex", "9.0") function bin:or($a as xs:base64Binary?, $b as xs:base64Binary?) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:xor($a as xs:base64Binary?, $b as xs:base64Binary?) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:and($a as xs:base64Binary?, $b as xs:base64Binary?) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:not($in as xs:base64Binary?) as xs:base64Binary? external;
declare %a:since("basex", "9.0") function bin:shift($in as xs:base64Binary?, $by as xs:integer) as xs:base64Binary? external;


more general / nicer transformation of courses

declare function local:transform($input as item()*) as item()* {
for $node in $input
   return
      typeswitch($node)
        case element()
         return
          if (name($node) != 'name') then
              element {name($node)} {
                if (name($node) = 'courses') then
                    for $na in distinct-values($node/course/taken_by/student/name/text()) return element {'newET0'} {  for $nu in distinct-values($node/course/taken_by/student[name/text() = $na]/@sno) return
                  element {'newET00'} {attribute {'sno'} {$nu}},
                  element {'name'} {$na}
                  }
                else (),
                for $att in $node/@*
                      return attribute {name($att)} {$att}
                ,
                for $child in $node
                   return local:transform($child/node())

              }
          else ()
        default return $node
};

local:transform(doc("test.xml")/courses)

<courses>
{let $root := doc("test.xml")/courses
 for $co in $root/course
  return <course cno="{ $co/@cno }">
<title>{$co/title/text()}</title>
<taken_by>
{ for $student in $co/taken_by
return <student sno="{$student/student/@sno }">
<grade>{$student/student/grade/text()}</grade>
</student>
}
</taken_by>
</course>
}
{
let $root := doc("test.xml")/courses
for $na in distinct-values($root/course/taken_by/student/name/text())
return <newET0>
{ for $nu in distinct-values($root/course/taken_by/student[name/text() =
$na]/@sno)
return <newET00 sno="{ $nu }" />,
<name> { $na } </name>
}
</newET0>
}
</courses>


[FIX] use POST also for resource specific query

(:~
 : Query resources.
 :
 : @author Christian Grün, BaseX GmbH, 2014-15
 :)
module namespace _ = 'dba/databases';

import module namespace cons = 'dba/cons' at '../../modules/cons.xqm';
import module namespace util = 'dba/util' at '../../modules/util.xqm';

(:~
 : Runs a query on a document and returns the result as string.
 : @param  $name      name of database
 : @param  $resource  resource
 : @param  $query     query
 : @return result string
 :)
declare
  %rest:POST("{$query}")
  %rest:path("/dba/query-resource")
  %rest:query-param("name",     "{$name}")
  %rest:query-param("resource", "{$resource}")
  %output:method("text")
function _:query-resource(
  $name      as xs:string,
  $resource  as xs:string,
  $query     as xs:string
) as xs:string {
  cons:check(),
  let $query := if($query) then $query else '.'
  return util:query($query, "'': db:open($name, $resource)", map {
    'name': $name, 'resource': $resource
  })
};

(:~
 : Query resources.
 :
 : @author Christian Grün, BaseX GmbH, 2014-15
 :)
module namespace _ = 'dba/databases';

import module namespace cons = 'dba/cons' at '../../modules/cons.xqm';
import module namespace util = 'dba/util' at '../../modules/util.xqm';

(:~
 : Runs a query on a document and returns the result as string.
 : @param  $name      name of database
 : @param  $resource  resource
 : @param  $query     query
 : @return result string
 :)
declare
  %rest:POST
  %rest:path("/dba/query-resource")
  %rest:query-param("name",     "{$name}")
  %rest:query-param("resource", "{$resource}")
  %rest:query-param("query",    "{$query}")
  %output:method("text")
function _:query-resource(
  $name      as xs:string,
  $resource  as xs:string,
  $query     as xs:string
) as xs:string {
  cons:check(),
  let $query := if($query) then $query else '.'
  return util:query($query, "'': db:open($name, $resource)", map {
    'name': $name, 'resource': $resource
  })
};


Fix position query for probes.

Fix position query for probes.

; datasetProbeValues
(fn [dataset samples probes]
  (let [probemap (:probemap (car (query {:select [:probemap]
                                         :from [:dataset]
                                         :where [:= :name dataset]})))
        position (if probemap
                    ((xena-query {:select ["name" "position"]
                                  :from [probemap]
                                  :where [:in "name" probes]}) "position")
                    nil)]
    [position
     (fetch [{:table dataset
              :columns probes
              :samples samples}])]))

; datasetProbeValues
(fn [dataset samples probes]
  (let [probemap (:probemap (car (query {:select [:probemap]
                                         :from [:dataset]
                                         :where [:= :name dataset]})))
        position (if probemap
                    (xena-query {:select ["name" "position"] :from [probemap] :where [:in :name probes]})
                    nil)]
    [position
     (fetch [{:table dataset
              :columns probes
              :samples samples}])]))


[test] Re-add item-separator serialization tests

(:
 : 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")
};


Changed GET param for consistency

Changed GET param for consistency

import module namespace notes="http://cefn.com/readinglog/notes" at "/home/cefn/Documents/highwire/participatory firmware design/readinglog/scripts/server/xquery/lib/notes.xq";
import module namespace template="http://cefn.com/readinglog/template" at "/home/cefn/Documents/highwire/participatory firmware design/readinglog/scripts/server/xquery/lib/template.xq";
declare default element namespace "http://www.w3.org/1999/xhtml";

declare variable $type external;

template:webpage(

{$type}

		{for $heading in notes:notesoftype($type)[self::p][text()] (: consider only non-empty paragraphs:)
			return

					{string($heading)}
					{notes:paperlinks($heading)}

		}

)

import module namespace notes="http://cefn.com/readinglog/notes" at "/home/cefn/Documents/highwire/participatory firmware design/readinglog/scripts/server/xquery/lib/notes.xq";
import module namespace template="http://cefn.com/readinglog/template" at "/home/cefn/Documents/highwire/participatory firmware design/readinglog/scripts/server/xquery/lib/template.xq";
declare default element namespace "http://www.w3.org/1999/xhtml";

declare variable $match external;

template:webpage(

{$match}

		{for $heading in notes:notesoftype($match)[self::p][text()] (: consider only non-empty paragraphs:)
			return

					{string($heading)}
					{notes:paperlinks($heading)}

		}

)