db:open(), xquery:eval(), and path()

Saturday, 16 November 2013 · 6 messages · last reply 17 Nov 2013
IL
Imsieke, Gerrit, le-tex16 Nov 2013 23:57 #
I think that under certain conditions, the path() function does not return the proper paths. Here’s an example that works ok:
for $doc in <doc><a/><b><c/></b></doc>
let $nodes as element(*)* := xquery:eval("$doc//*", map{"doc":=$doc})
return
   for $node in $nodes
   return <result path="{path($node)}" name="{name($node)}"/>

⇒
<result path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}a[1]"
name="a"/>
<result path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}b[1]"
name="b"/>
<result
path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}b[1]/Q{}c[1]"
name="c"/>
Now I create a database 'doc' with the document 'doc.xml' and invoke the slightly modified query:
for $doc in db:open('doc', 'doc.xml')/*
let $nodes as element(*)* := xquery:eval("$doc//*", map{"doc":=$doc})
return
   for $node in $nodes
   return <result path="{path($node)}" name="{name($node)}"/>

⇒
<result path="Q{http://www.w3.org/2005/xpath-functions}root()" name="a"/>
<result path="Q{http://www.w3.org/2005/xpath-functions}root()" name="b"/>
<result path="Q{http://www.w3.org/2005/xpath-functions}root()" name="c"/>
The element names are still known, but not their paths. Is it a bug or am I missing something? Gerrit
IL
Imsieke, Gerrit, le-tex17 Nov 2013 02:51 #
Probably related: db:node-id(xquery:eval("db:open('doc', 'doc.xml')/*")) ⇒ 0 db:node-id(db:open('doc', 'doc.xml')/*) ⇒ 1
Quoted text · le-tex · 44 lines
On 16.11.2013 23:57, Imsieke, Gerrit, le-tex wrote: > I think that under certain conditions, the path() function does not > return the proper paths. > > Here’s an example that works ok: > > for $doc in <doc><a/><b><c/></b></doc> > let $nodes as element(*)* := xquery:eval("$doc//*", map{"doc":=$doc}) > return > for $node in $nodes > return <result path="{path($node)}" name="{name($node)}"/> > > ⇒ > <result path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}a[1]" > name="a"/> > <result path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}b[1]" > name="b"/> > <result > path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}b[1]/Q{}c[1]" > name="c"/> > > Now I create a database 'doc' with the document 'doc.xml' and invoke the > slightly modified query: > > for $doc in db:open('doc', 'doc.xml')/* > let $nodes as element(*)* := xquery:eval("$doc//*", map{"doc":=$doc}) > return > for $node in $nodes > return <result path="{path($node)}" name="{name($node)}"/> > > ⇒ > <result path="Q{http://www.w3.org/2005/xpath-functions}root()" name="a"/> > <result path="Q{http://www.w3.org/2005/xpath-functions}root()" name="b"/> > <result path="Q{http://www.w3.org/2005/xpath-functions}root()" name="c"/> > > The element names are still known, but not their paths. Is it a bug or > am I missing something? > > Gerrit > > _______________________________________________ > BaseX-Talk mailing list > BaseX-Talk at mailman.uni-konstanz.de > https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk
-- Gerrit Imsieke Geschäftsführer / Managing Director le-tex publishing services GmbH Weissenfelser Str. 84, 04229 Leipzig, Germany Phone +49 341 355356 110, Fax +49 341 355356 510 gerrit.imsieke at le-tex.de, http://www.le-tex.de Registergericht / Commercial Register: Amtsgericht Leipzig Registernummer / Registration Number: HRB 24930 Geschäftsführer: Gerrit Imsieke, Svea Jelonek, Thomas Schmidt, Dr. Reinhard Vöckler
CG
Christian Grün17 Nov 2013 12:04 #
Hi Gerrit,
Quoted text · Imsieke, Gerrit, le-tex · 2 lines
> db:node-id(xquery:eval("db:open('doc', 'doc.xml')/*")) > => 0
some quick feedback (I'll further look into this): when running xquery:eval, a main-memory copy of the original node is created, which may have another node id than the original node. To get the node id of the original node, you'll have to embed your db:node-id call into the xquery:eval code:
  xquery:eval("db:node-id(db:open('doc', 'doc.xml')/*)")
Hope this helps, Christian
Quoted text · le-tex · 76 lines
On Sun, Nov 17, 2013 at 2:51 AM, Imsieke, Gerrit, le-tex <gerrit.imsieke at le-tex.de> wrote: > Probably related: > > > db:node-id(db:open('doc', 'doc.xml')/*) > => 1 > > > > > On 16.11.2013 23:57, Imsieke, Gerrit, le-tex wrote: >> >> I think that under certain conditions, the path() function does not >> return the proper paths. >> >> Here's an example that works ok: >> >> for $doc in <doc><a/><b><c/></b></doc> >> let $nodes as element(*)* := xquery:eval("$doc//*", map{"doc":=$doc}) >> return >> for $node in $nodes >> return <result path="{path($node)}" name="{name($node)}"/> >> >> => >> <result path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}a[1]" >> name="a"/> >> <result path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}b[1]" >> name="b"/> >> <result >> path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}b[1]/Q{}c[1]" >> name="c"/> >> >> Now I create a database 'doc' with the document 'doc.xml' and invoke the >> slightly modified query: >> >> for $doc in db:open('doc', 'doc.xml')/* >> let $nodes as element(*)* := xquery:eval("$doc//*", map{"doc":=$doc}) >> return >> for $node in $nodes >> return <result path="{path($node)}" name="{name($node)}"/> >> >> => >> <result path="Q{http://www.w3.org/2005/xpath-functions}root()" name="a"/> >> <result path="Q{http://www.w3.org/2005/xpath-functions}root()" name="b"/> >> <result path="Q{http://www.w3.org/2005/xpath-functions}root()" name="c"/> >> >> The element names are still known, but not their paths. Is it a bug or >> am I missing something? >> >> Gerrit >> >> _______________________________________________ >> BaseX-Talk mailing list >> BaseX-Talk at mailman.uni-konstanz.de >> https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk > > > -- > Gerrit Imsieke > Geschäftsführer / Managing Director > le-tex publishing services GmbH > Weissenfelser Str. 84, 04229 Leipzig, Germany > Phone +49 341 355356 110, Fax +49 341 355356 510 > gerrit.imsieke at le-tex.de, http://www.le-tex.de > > Registergericht / Commercial Register: Amtsgericht Leipzig > Registernummer / Registration Number: HRB 24930 > > Geschäftsführer: Gerrit Imsieke, Svea Jelonek, > Thomas Schmidt, Dr. Reinhard Vöckler > > _______________________________________________ > BaseX-Talk mailing list > BaseX-Talk at mailman.uni-konstanz.de > https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk
CG
Christian Grünin reply to Imsieke, Gerrit, le-tex, 16 Nov 2013, 23:5717 Nov 2013 12:20 #
Quoted text · Imsieke, Gerrit, le-tex · 5 lines
> for $doc in db:open('doc', 'doc.xml')/* > let $nodes as element(*)* := xquery:eval("$doc//*", map{"doc":=$doc}) > return > for $node in $nodes > return <result path="{path($node)}" name="{name($node)}"/>
I tried to rewrite you query into sth. that may be of help for you…
  for $doc in db:open('doc', 'doc.xml')/*
  let $query := '$doc//* ! <result path="{path()}" name="{name()}"/>'
  return xquery:eval($query, map{"doc":=$doc})
…but I guess your real use case is somewhat more complex, so feel free to give us an updated example. Christian
IL
Imsieke, Gerrit, le-texin reply to Christian Grün, 17 Nov 2013, 12:0417 Nov 2013 16:02 #
Ah, I see. It just felt too PHPish to synthesize the whole query as a string, therefore I thought I might use xquery:eval() ad libitum in the middle of a query and that it would operate on the same database as the static remainder of the query. And of course it is harder to debug if the whole query is a string, syntax-aware editor support is unavailable, etc. I wanted to have a generic, configurable RESTXQ interface for retrieving document fragments according to fragmentation rules that are defined elsewhere, by means of an XPath expression. This expression may be for example '//*:div[not(ancestor::*:div)][not(*:divGen)]' for a certain class of TEI documents, or '//(*:chapter | *:part | *:appendix | *:preface)' for DocBook. This expression is passed to the function sxedit:list-frags() that retrieves the headings of all fragments, as in https://github.com/gimsieke/sxedit/blob/master/lib/basex/restxq/sxedit.xqm#L90, and it is also supplied as an argument to the function that is supposed to retrieve the fragments, inserting placeholder elements whenever a nested fragment is encountered. Another configurable option in that module is an expression, $doc-condition, that filters the available databases for documents that meet certain criteria, for example, '[namespace-uri(/*) = ''http://www.tei-c.org/ns/1.0'']'. I’ll have to deal with writing back the (edited) fragments; maybe I’ll contact you folks off-list soon for some guidance on forging the updating queries because I never did updating queries before ;) Gerrit
Quoted text · Christian Grün · 94 lines
On 17.11.2013 12:04, Christian Grün wrote: > Hi Gerrit, > >> db:node-id(xquery:eval("db:open('doc', 'doc.xml')/*")) >> => 0 > > some quick feedback (I'll further look into this): when running > xquery:eval, a main-memory copy of the original node is created, which > may have another node id than the original node. To get the node id of > the original node, you'll have to embed your db:node-id call into the > xquery:eval code: > > xquery:eval("db:node-id(db:open('doc', 'doc.xml')/*)") > > Hope this helps, > Christian > ___________________________ > > On Sun, Nov 17, 2013 at 2:51 AM, Imsieke, Gerrit, le-tex > <gerrit.imsieke at le-tex.de> wrote: >> Probably related: >> >> >> db:node-id(db:open('doc', 'doc.xml')/*) >> => 1 >> >> >> >> >> On 16.11.2013 23:57, Imsieke, Gerrit, le-tex wrote: >>> >>> I think that under certain conditions, the path() function does not >>> return the proper paths. >>> >>> Here's an example that works ok: >>> >>> for $doc in <doc><a/><b><c/></b></doc> >>> let $nodes as element(*)* := xquery:eval("$doc//*", map{"doc":=$doc}) >>> return >>> for $node in $nodes >>> return <result path="{path($node)}" name="{name($node)}"/> >>> >>> => >>> <result path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}a[1]" >>> name="a"/> >>> <result path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}b[1]" >>> name="b"/> >>> <result >>> path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}b[1]/Q{}c[1]" >>> name="c"/> >>> >>> Now I create a database 'doc' with the document 'doc.xml' and invoke the >>> slightly modified query: >>> >>> for $doc in db:open('doc', 'doc.xml')/* >>> let $nodes as element(*)* := xquery:eval("$doc//*", map{"doc":=$doc}) >>> return >>> for $node in $nodes >>> return <result path="{path($node)}" name="{name($node)}"/> >>> >>> => >>> <result path="Q{http://www.w3.org/2005/xpath-functions}root()" name="a"/> >>> <result path="Q{http://www.w3.org/2005/xpath-functions}root()" name="b"/> >>> <result path="Q{http://www.w3.org/2005/xpath-functions}root()" name="c"/> >>> >>> The element names are still known, but not their paths. Is it a bug or >>> am I missing something? >>> >>> Gerrit >>> >>> _______________________________________________ >>> BaseX-Talk mailing list >>> BaseX-Talk at mailman.uni-konstanz.de >>> https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk >> >> >> -- >> Gerrit Imsieke >> Geschäftsführer / Managing Director >> le-tex publishing services GmbH >> Weissenfelser Str. 84, 04229 Leipzig, Germany >> Phone +49 341 355356 110, Fax +49 341 355356 510 >> gerrit.imsieke at le-tex.de, http://www.le-tex.de >> >> Registergericht / Commercial Register: Amtsgericht Leipzig >> Registernummer / Registration Number: HRB 24930 >> >> Geschäftsführer: Gerrit Imsieke, Svea Jelonek, >> Thomas Schmidt, Dr. Reinhard Vöckler >> >> _______________________________________________ >> BaseX-Talk mailing list >> BaseX-Talk at mailman.uni-konstanz.de >> https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk
-- Gerrit Imsieke Geschäftsführer / Managing Director le-tex publishing services GmbH Weissenfelser Str. 84, 04229 Leipzig, Germany Phone +49 341 355356 110, Fax +49 341 355356 510 gerrit.imsieke at le-tex.de, http://www.le-tex.de Registergericht / Commercial Register: Amtsgericht Leipzig Registernummer / Registration Number: HRB 24930 Geschäftsführer: Gerrit Imsieke, Svea Jelonek, Thomas Schmidt, Dr. Reinhard Vöckler
CG
Christian Grün17 Nov 2013 16:12 #
Quoted text · Imsieke, Gerrit, le-tex · 4 lines
> Ah, I see. It just felt too PHPish to synthesize the whole query as a > string, therefore I thought I might use xquery:eval() ad libitum in the > middle of a query and that it would operate on the same database as the > static remainder of the query.
…completely true. When thinking of our own projects, I can’t remember any in which we actually use xquery:eval (aka evil) due to that reasons. One way out would be to provide dynamic evaluation of pure XPath 1.0 expressions with fixed data instances, but this is currently out of scope. You could as well limit the eval output to node ids and reopen them from the actual query. Christian
Quoted text · Imsieke, Gerrit, le-tex · 151 lines
> And of course it is harder to debug if the whole query is a string, > syntax-aware editor support is unavailable, etc. > > I wanted to have a generic, configurable RESTXQ interface for retrieving > document fragments according to fragmentation rules that are defined > elsewhere, by means of an XPath expression. This expression may be for > example '//*:div[not(ancestor::*:div)][not(*:divGen)]' for a certain class > of TEI documents, or '//(*:chapter | *:part | *:appendix | *:preface)' for > DocBook. > > This expression is passed to the function sxedit:list-frags() that retrieves > the headings of all fragments, as in > https://github.com/gimsieke/sxedit/blob/master/lib/basex/restxq/sxedit.xqm#L90, > and it is also supplied as an argument to the function that is supposed to > retrieve the fragments, inserting placeholder elements whenever a nested > fragment is encountered. > > Another configurable option in that module is an expression, $doc-condition, > that filters the available databases for documents that meet certain > criteria, for example, '[namespace-uri(/*) = > ''http://www.tei-c.org/ns/1.0'']'. > > I’ll have to deal with writing back the (edited) fragments; maybe I’ll > contact you folks off-list soon for some guidance on forging the updating > queries because I never did updating queries before ;) > > Gerrit > > > > On 17.11.2013 12:04, Christian Grün wrote: >> >> Hi Gerrit, >> >>> db:node-id(xquery:eval("db:open('doc', 'doc.xml')/*")) >>> => 0 >> >> >> some quick feedback (I'll further look into this): when running >> xquery:eval, a main-memory copy of the original node is created, which >> may have another node id than the original node. To get the node id of >> the original node, you'll have to embed your db:node-id call into the >> xquery:eval code: >> >> xquery:eval("db:node-id(db:open('doc', 'doc.xml')/*)") >> >> Hope this helps, >> Christian >> ___________________________ >> >> On Sun, Nov 17, 2013 at 2:51 AM, Imsieke, Gerrit, le-tex >> <gerrit.imsieke at le-tex.de> wrote: >>> >>> Probably related: >>> >>> >>> db:node-id(db:open('doc', 'doc.xml')/*) >>> => 1 >>> >>> >>> >>> >>> On 16.11.2013 23:57, Imsieke, Gerrit, le-tex wrote: >>>> >>>> >>>> I think that under certain conditions, the path() function does not >>>> return the proper paths. >>>> >>>> Here's an example that works ok: >>>> >>>> for $doc in <doc><a/><b><c/></b></doc> >>>> let $nodes as element(*)* := xquery:eval("$doc//*", map{"doc":=$doc}) >>>> return >>>> for $node in $nodes >>>> return <result path="{path($node)}" name="{name($node)}"/> >>>> >>>> => >>>> <result path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}a[1]" >>>> name="a"/> >>>> <result path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}b[1]" >>>> name="b"/> >>>> <result >>>> path="Q{http://www.w3.org/2005/xpath-functions}root()/Q{}b[1]/Q{}c[1]" >>>> name="c"/> >>>> >>>> Now I create a database 'doc' with the document 'doc.xml' and invoke the >>>> slightly modified query: >>>> >>>> for $doc in db:open('doc', 'doc.xml')/* >>>> let $nodes as element(*)* := xquery:eval("$doc//*", map{"doc":=$doc}) >>>> return >>>> for $node in $nodes >>>> return <result path="{path($node)}" name="{name($node)}"/> >>>> >>>> => >>>> <result path="Q{http://www.w3.org/2005/xpath-functions}root()" >>>> name="a"/> >>>> <result path="Q{http://www.w3.org/2005/xpath-functions}root()" >>>> name="b"/> >>>> <result path="Q{http://www.w3.org/2005/xpath-functions}root()" >>>> name="c"/> >>>> >>>> The element names are still known, but not their paths. Is it a bug or >>>> am I missing something? >>>> >>>> Gerrit >>>> >>>> _______________________________________________ >>>> BaseX-Talk mailing list >>>> BaseX-Talk at mailman.uni-konstanz.de >>>> https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk >>> >>> >>> >>> -- >>> Gerrit Imsieke >>> Geschäftsführer / Managing Director >>> le-tex publishing services GmbH >>> Weissenfelser Str. 84, 04229 Leipzig, Germany >>> Phone +49 341 355356 110, Fax +49 341 355356 510 >>> gerrit.imsieke at le-tex.de, http://www.le-tex.de >>> >>> Registergericht / Commercial Register: Amtsgericht Leipzig >>> Registernummer / Registration Number: HRB 24930 >>> >>> Geschäftsführer: Gerrit Imsieke, Svea Jelonek, >>> Thomas Schmidt, Dr. Reinhard Vöckler >>> >>> _______________________________________________ >>> BaseX-Talk mailing list >>> BaseX-Talk at mailman.uni-konstanz.de >>> https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk > > > -- > Gerrit Imsieke > Geschäftsführer / Managing Director > le-tex publishing services GmbH > Weissenfelser Str. 84, 04229 Leipzig, Germany > Phone +49 341 355356 110, Fax +49 341 355356 510 > gerrit.imsieke at le-tex.de, http://www.le-tex.de > > Registergericht / Commercial Register: Amtsgericht Leipzig > Registernummer / Registration Number: HRB 24930 > > Geschäftsführer: Gerrit Imsieke, Svea Jelonek, > Thomas Schmidt, Dr. Reinhard Vöckler > _______________________________________________ > BaseX-Talk mailing list > BaseX-Talk at mailman.uni-konstanz.de > https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk

⚡Generated with XQuery