(:
: eXide - web-based XQuery IDE
:
: Copyright (C) 2011 Wolfgang Meier
:
: This program is free software: you can redistribute it and/or modify
: it under the terms of the GNU General Public License as published by
: the Free Software Foundation, either version 3 of the License, or
: (at your option) any later version.
:
: This program 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 General Public License for more details.
:
: You should have received a copy of the GNU General Public License
: along with this program. If not, see .
:)
xquery version "1.0";
(:~
Post-processes query results for the sandbox application. The
controller first sends the user-supplied query to XQueryServlet
for evaluation. The result is then passed to this script, which
stores the result set into the HTTP session and returns the number
of hits and time elapsed.
Subsequent requests from the sandbox application may retrieve single
items from the result set stored in the session (see controller).
:)
declare namespace sandbox="http://exist-db.org/xquery/sandbox";
declare option exist:serialize "method=xml media-type=text/xml omit-xml-declaration=no indent=no";
(:~
: Check which namespace declarations have to be output.
:)
declare function sandbox:namespace-decls($elem as element(), $namespaces as xs:string*) {
for $node in ($elem, $elem/@*)
let $name := node-name($node)
let $ns := namespace-uri-from-QName($name)
let $prefix := prefix-from-QName($name)
return
if ($ns and empty(index-of($namespaces, $ns))) then
else
()
};
(:~
Pretty print an XML fragment. Returns HTML to highlight the XML syntax.
:)
declare function sandbox:pretty-print($node as item(), $namespaces as xs:string*) {
typeswitch ($node)
case $elem as element(exist:match) return
{$elem/node()}
case $elem as element() return
let $nsDecls := sandbox:namespace-decls($elem, $namespaces)
let $newNamespaces :=
if (empty($nsDecls)) then
$namespaces
else
($namespaces, $nsDecls/@uri/string())
return
<
{node-name($elem)}
{
for $nsDecl in $nsDecls
return (
' ',
{
if ($nsDecl/@prefix != '') then
concat("xmlns:", $nsDecl/@prefix/string())
else
"xmlns"
}
, '="',
{$nsDecl/@uri/string()},
'"'
)
}
{
for $attr in $elem/@*
return (
' ', {node-name($attr)},
'="', {$attr/string()}, '"'
)
}
{
let $children := $elem/node()
return
if (count($children) gt 0) then (
>,
for $child in $children
return
sandbox:pretty-print($child, $newNamespaces),
</,
{node-name($elem)},
>
) else
/>
}
case $text as text() return
{$text}
case $comment as comment() return
case $pi as processing-instruction() return
<?{$pi/string()}?>
default return
$node
};
(:~ Retrieve a single query result. :)
declare function sandbox:retrieve($num as xs:integer) as element() {
let $cached := session:get-attribute("cached")
let $node := $cached[$num]
let $item :=
if ($node instance of node()) then
util:expand($node, 'indent=yes')
else
$node
let $documentURI :=if ($node instance of node()) then document-uri(root($node)) else ()
return
{
if (string-length($documentURI) > 0) then
{$num}
else
()
}
{ sandbox:pretty-print($item, ()) }
};
(:~ Take the query results and store them into the HTTP session. :)
declare function sandbox:store-in-session($results as item()*) as element(result) {
let $null := session:set-attribute('cached', $results)
let $startTime := request:get-attribute("start-time")
let $elapsed := if ($startTime) then seconds-from-duration(current-time() - xs:time($startTime)) else 0
return
};
(: When a query has been executed, its results will be passed into
this script in the request attribute 'results'. The result is then
stored into the HTTP session. Subsequent requests from the sandbox
can reference a result item in the session by passing parameter 'num'.
:)
session:create(),
let $input := request:get-data()
let $results := request:get-attribute("results")
let $pos := xs:integer(request:get-parameter("num", ()))
return
if (string-length($input) gt 0) then
$input
else if ($pos) then
sandbox:retrieve($pos)
else
sandbox:store-in-session($results)