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')/*)
⇒ 1Quoted 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
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
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 ;)
GerritQuoted 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.
ChristianQuoted 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
Written for BaseX 7.7. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery