I’ve been learning how to use the BaseX webapp, and below is one of the first test scripts for the REST interface I wrote.
No problems with this script.
declare option output:omit-xml-declaration "no";
declare option output:method "xhtml";
(:
declare variable $contains :=
try { request:parameter( 'contains' ) }
catch basex:http { '' };
"All query parameters that have not been processed before will be treated as variable assignments"
:)
declare variable $contains as xs:string external := "";
declare function local:f0line( $f ) as node() {
(: build a list item with function name and function values :)I
<li><b>{fn:function-name($f)}:</b> {$f()}</li>
};
declare variable $CTX := try { . } catch err:XPDY0002 { () };
declare variable $DB := try { db:name( $CTX[1] ) } catch err:XPTY0004 { "" };
(: Could be, if (): [XPTY0004] node() expected, empty sequence found.
but not sure if that's the only possible case. :)
<html><head><title>test</title></head><body>
<div id="context">
<h3>Database: { $DB }</h3>
<h3>Context documents (.)</h3>
<ol>
{ for $doc in $CTX return <li><b>{base-uri($doc)}</b></li> }
</ol>
</div>
<div id="request">
<h3>HTTP Request</h3>
<ul>
{ for $f in ( request:method#0, request:scheme#0, request:hostname#0, request:port#0,
request:path#0, request:query#0, request:uri#0, request:context-path#0, request:address#0,
request:remote-hostname#0, request:remote-address#0, request:remote-port#0 )
return local:f0line($f) }
</ul>
</div>
<div id="params">
<h3>Request Parameters:</h3>
<ul>
{ for $param in request:parameter-names() return
<li><b>{$param}:</b> {request:parameter($param)}</li> }
</ul>
</div>
<div id="headers">
<h3>Headers</h3>
<ul>
{ for $header in request:header-names() return
<li><b>{$header}:</b> {request:header($header)}</li> }
</ul>
</div>
<div id="cookies" >
<h3>Cookies</h3>
<ul>
{ for $cookie in request:cookie-names() return
<li><b>{$cookie}:</b> {request:cookie($cookie)}</li> }
</ul>
</div>
<div id="xslt">
<h4>XSLT</h4>
<ul>
<li><b>xslt:processor: { xslt:processor()},   xslt:version: { xslt:version()}</b></li>
</ul>
</div>
</body></html>
I’m now trying to learn RESTXQ programming, so I was trying to do the same sort of thing from a RESTXQ module.
I was getting an error from the line where (: request:query#0, :) is now commented out, and added the line:
<li>{ request:query( ), function-name(request:query#0)}</li>
And I see that what happens is that it’s the latter function-name(request:query#0) that is generating an error, but only when there is no query string in my request. An empty query string, i.e. “
http://localhost/basex/test?” , for example, works. But “
http://localhost/basex/test returns:
Stopped at /usr/local/tomcat/webapps/basex/test.xqm, 33/66:
[XPTY0004] Cannot convert empty-sequence() to xs:string: ().
I assume this has something to do with how RESTXQ processes form and request parameters, and I probably don’t actually need to do it this way, but I was wondering what exactly is the source of the problem with doing something like this or if there is an obvious work around. Maybe writing another local function to wrap around request:query and to use in that loop.
( One reason I chose that test to convert to RESTXQ was that it wasn’t obvious to be from the docs if I could mix those different access methods, and so what was surprising was that it mostly worked — only that one function failed (so far)).
declare function test:f0line( $f ) as node() {
(: build a list item with function name and function values :)
<li><b>{fn:function-name($f)}:</b> {$f()}</li>
};
(:~
: Generates a welcome page.
: @return HTML page
:)
declare
%rest:path("test")
%output:method("xhtml")
%output:omit-xml-declaration("no")
%output:doctype-public("-//W3C//DTD XHTML 1.0 Transitional//EN")
function test:test(
<head>
<title>BaseX HTTP Services</title>
<link rel="stylesheet" type="text/css" href="static/style.css"/>
</head>
<body>
<div class="right"><a href='/'><img src="static/basex.svg"/></a></div>
<h1>TEST</h1>
<div id="debug" >
<ul>
<li>{ request:query( ), function-name(request:query#0)}</li>
</ul>
</div>
<div id="request">
<h3>HTTP Request</h3>
<ul>
{ for $f in ( request:method#0, request:scheme#0, request:hostname#0, request:port#0,
request:path#0, (: request:query#0, :) request:uri#0, request:context-path#0, request:address#0,
request:remote-hostname#0, request:remote-address#0, request:remote-port#0 )
return test:f0line($f) }
</ul>
</div>
</body>
</html>
};