Hi David,
I like your solution. Whenever I have used xdmp:eval to date I have
preformed a string literal to pass i rather than employ external variables
- it feels slightly lazy but easy.
The only downside I know to using that method to construct the string is
if the string actually contains XQuery { } syntax that you _dont_ want
evaluated until you execute the xdmp:eval - such as if you were setting a
variable from the other DB and using it as a part of your evaluated query.
A bit contrived but something like this.....
let $query := <q>
let $localdbval := /abc/def/ghi[1]
myfunc(<anode>{$localdbval}</anode>)
</q>
where rather than remembering to escape quotes you'll have to escape
braces, using double braces.
Andy
David Sewell <[EMAIL PROTECTED]>
Sent by: [EMAIL PROTECTED]
18/07/2007 19:59
Please respond to
General Mark Logic Developer Discussion <[email protected]>
To
General XQZone Discussion <[EMAIL PROTECTED]>
cc
Subject
[MarkLogic Dev General] Taming xdmp:eval() syntax
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
----------------------------------------------------------------------
The information contained in this e-mail and any subsequent
correspondence is private and confidential and intended solely
for the named recipient(s). If you are not a named recipient,
you must not copy, distribute, or disseminate the information,
open any attachment, or take any action in reliance on it. If you
have received the e-mail in error, please notify the sender and delete
the e-mail.
Any views or opinions expressed in this e-mail are those of the
individual sender, unless otherwise stated. Although this e-mail has
been scanned for viruses you should rely on your own virus check, as
the sender accepts no liability for any damage arising out of any bug
or virus infection.
John Wiley & Sons Limited is a private limited company registered in
England with registered number 641132.
Registered office address: The Atrium, Southern Gate, Chichester,
West Sussex, PO19 8SQ.
----------------------------------------------------------------------
_______________________________________________
General mailing list
[email protected]
http://xqzone.com/mailman/listinfo/general