dynamically evaluate XPath

Monday, 11 November 2013 · 3 messages
IL
Imsieke, Gerrit, le-tex11 Nov 2013 12:44 #
I have a RESTXQ path/function that is supposed to retrieve a document fragment, restricted to an XPath expression that is given as a query parameter, i.e., as a string. The list of possible fragment XPaths has been calculated using path() by another function, and the user of a Web application may choose to retrieve any of the fragments. An example for such a path would be '/Q{http://www.tei-c.org/ns/1.0}TEI[1]/Q{http://www.tei-c.org/ns/1.0}text[1]/Q{http://www.tei-c.org/ns/1.0}front[1]/Q{http://www.tei-c.org/ns/1.0}div[3]'. Is there a better solution than the following, whose performance is of course quite poor (around 2 seconds execution time for the given documents)? I’m thinking of something like saxon:evaluate() or the XSLT 3 instruction xsl:evaluate. Maybe I’m just unaware of the obvious solution based upon XQuery 3 or a BaseX extension. Gerrit
declare
   %rest:path("/content/fragment/{$db}/{$doc}")
   %rest:query-param("xpath", "{$xpath}")
   %rest:GET
   function page:get-frags(
     $db as xs:string,
     $doc as xs:string,
     $xpath as xs:string
   )
     as item()*
{
   <response>
     { for $doc in db:open($db, $doc)
       return $doc//*[path(.) eq $xpath] }
   </response>
};
CG
Christian Grün11 Nov 2013 13:49 #
Hi Gerrit, you are probably looking for the xquery:eval function [1]:
  xquery:eval( "db:open('" || $db || "', '" || $doc || "')" || $xpath)
You can make the query string safer by bind ing variables to the evaluated expression:
  xquery:eval( "db:open($db, $doc)" || $xpath,
    map { "db" := $db, "doc" = $doc })
Hope this helps, Christian [1] http://docs.basex.org/wiki/XQuery_Module
Quoted text · le-tex · 11 lines
On Mon, Nov 11, 2013 at 12:44 PM, Imsieke, Gerrit, le-tex < gerrit.imsieke at le-tex.de> wrote: > I have a RESTXQ path/function that is supposed to retrieve a document > fragment, restricted to an XPath expression that is given as a query > parameter, i.e., as a string. The list of possible fragment XPaths has been > calculated using path() by another function, and the user of a Web > application may choose to retrieve any of the fragments. > > An example for such a path would be > '/Q{
Quoted text · Imsieke, Gerrit, le-tex · 3 lines
> > Is there a better solution than the following, whose performance is of > course quite poor (around 2 seconds execution time for the given
documents)?
Quoted text · Imsieke, Gerrit, le-tex · 28 lines
> I’m thinking of something like saxon:evaluate() or the XSLT 3 instruction > xsl:evaluate. > > Maybe I’m just unaware of the obvious solution based upon XQuery 3 or a > BaseX extension. > > Gerrit > > declare > %rest:path("/content/fragment/{$db}/{$doc}") > %rest:query-param("xpath", "{$xpath}") > %rest:GET > function page:get-frags( > $db as xs:string, > $doc as xs:string, > $xpath as xs:string > ) > as item()* > { > <response> > { for $doc in db:open($db, $doc) > return $doc//*[path(.) eq $xpath] } > </response> > }; > _______________________________________________ > BaseX-Talk mailing list > BaseX-Talk at mailman.uni-konstanz.de > https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk
IL
Imsieke, Gerrit, le-tex11 Nov 2013 14:03 #
Thanks Christian, that’s it!
Quoted text · Christian Grün · 6 lines
On 11.11.2013 13:49, Christian Grün wrote: > Hi Gerrit, > > you are probably looking for the xquery:eval function [1]: > > xquery:eval( "db:open('" || $db || "', '" || $doc || "')" || $xpath)

⚡Generated with XQuery