We have been somewhat loathe to use xdmp:eval() because of its rather
ungainly syntax, what with having to define external variables and use
the <options><database>..</database></options> structure to pass a
database ID to the function. I'd like feedback on an alternate way of
calling the function that I've just been trying out.
Suppose I have a database named "Shakespeare" containing hamlet.xml. It
is not the default database for my app server, so I'll need to access it
using xdmp:eval(). I want to return all lines spoken by Hamlet containing
the word "slave", then all lines containing "fool". (For purposes of the
exercise I'll call cts:search twice rather than use an 'or' query.)
Here's what I'd call the typical way to construct the query:
let $terms := ("slave", "fool")
for $search in $terms
return xdmp:eval(
'
define variable $SEARCH as xs:string external
cts:search(doc("hamlet.xml")//speech[speaker[.="HAMLET"]]/line, $SEARCH)
',
(QName("", "SEARCH"), $search),
<options xmlns="xdmp:eval">
<database>{xdmp:database('Shakespeare')}</database>
</options>
)
where the query string is passed to xdmp:eval() as a literal string.
That does the job and is compact, but somewhat unreadable. Plus you have
to be careful to escape any ' used within the query.
Here is an alternate way of doing the same thing, longer but more
readable, producing the exact same results:
define variable $ShakespeareDB
{
<options xmlns="xdmp:eval">
<database>{xdmp:database('Shakespeare')}</database>
</options>
}
let $terms := ( "slave", "fool" )
for $search in $terms
let $query :=
<q>
cts:search(doc("hamlet.xml")//speech[speaker[.='HAMLET']]/line,
"{$search}")
</q>
return xdmp:eval(
$query,
(),
$ShakespeareDB
)
Here I'm defining the options node as a global variable, which of course
makes sense if I want to use the same options in more than one
xdmp:eval(). The main novelty is passing the query parameter to
xdmp:eval() as a variable containing a constructed <q> element, which
is cast as a string by xdmp:eval(). Because $query is a constructed
element, I can use standard XQuery { } syntax to embed variable
references that are expanded before $query is passed to xdmp:eval(),
so
"{$search}" ==> "slave" then "fool"
I'm getting the effect of external variables within xdmp:eval() without
the messiness of the external variables syntax.
Can anyone see a downside to this approach?
--
David Sewell, Editorial and Technical Manager
ROTUNDA, The University of Virginia Press
PO Box 801079, Charlottesville, VA 22904-4318 USA
Courier: 310 Old Ivy Way, Suite 302, Charlottesville VA 22903
Email: [EMAIL PROTECTED] Tel: +1 434 924 9973
Web: http://rotunda.upress.virginia.edu/
_______________________________________________
General mailing list
[email protected]
http://xqzone.com/mailman/listinfo/general