Refer to a specific document in a BaseX DB using XQuery
Thursday, 29 July 2010 · 6 messages · last reply 30 Jul 2010
C
cosmotron+basex29 Jul 2010 16:29 #
If I add two documents to a BaseX DB, let's say normal.xml and normal2.xml, is there a way to refer to each one individually?
I know about the doc() function, but it looks at the filesystem for their location, rather than in the database itself.
For instance, if I query with this: doc("normal.xml")/name , then I will get an error about normal.xml not being found.
I also tried: basex:db("my-db-name")/doc("normal.xml")/name and received the same error.
Thanks for any help!
MS
Michael Seiferle29 Jul 2010 16:42 #
Hi there,
the most convenient way to identify documents inside collections might be restricting the the query to a single document or a group of documents via matching the document-uri()
Quoted text · cosmotron+basex · 3 lines
> for $doc in basex:db('yourdb') > where matches(document-uri($doc),'test.xml') > return $doc
Please note that the document-uri() function only evaluates document-nodes, to test against inner nodes you should use base-uri($node) instead of document-uri():
Quoted text · cosmotron+basex · 3 lines
> for $node in basex:db('yourdb')//child > where matches(base-uri($node),'test.xml') > return $node
As there is no standardized way of handling collections of XML documents we are still looking forward to feedback regarding this issue.
Hope this helps, feel free to ask more otherwise.
Kind regards
Michael
Quoted text · cosmotron+basex · 15 lines
Am 29.07.2010 um 16:29 schrieb cosmotron+basex at gmail.com: > If I add two documents to a BaseX DB, let's say normal.xml and normal2.xml, is there a way to refer to each one individually? > > I know about the doc() function, but it looks at the filesystem for their location, rather than in the database itself. > > For instance, if I query with this: doc("normal.xml")/name , then I will get an error about normal.xml not being found. > > I also tried: basex:db("my-db-name")/doc("normal.xml")/name and received the same error. > > Thanks for any help! > > _______________________________________________ > BaseX-Talk mailing list > BaseX-Talk at mailman.uni-konstanz.de > https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk
MS
Hi Ryan,
sorry for misleading you, I was tricked by our commands myself. Instead of basex:db('name') which opens the DB as a database (thus the first document is added to the context) please use the collection('name') command:
Quoted text · Ryan Lewis · 2 lines
> for $doc in collection('test') > return $doc
Sorry for the inconvenience, the hint on using matches(document-uri(... should work correctly now. If you have any further questions feel free to ask.
Kind regards
Michael
Quoted text · Ryan Lewis · 59 lines
Am 29.07.2010 um 16:57 schrieb Ryan Lewis: > Hey, > > Thanks for the quick reply! > > I decided to do a simple query using basex:db(), and its results are... odd. Simply performing: >> for $doc in basex:db('yourdb') >> return $doc > only returns the first document in my database. I thought maybe the database was corrupt or something, so I tried: >> for $doc in /my_root_node >> return $doc > And that returned the entire structure of all documents in the database. > > Is that the normal functionality of basex:db()? If so, then I can not iterate through it as per your examples, since it will only see the first document. > > -- > Ryan Lewis '09 > Clarkson University > > > On Thu, Jul 29, 2010 at 10:42 AM, Michael Seiferle <michael.seiferle at uni-konstanz.de> wrote: > Hi there, > > the most convenient way to identify documents inside collections might be restricting the the query to a single document or a group of documents via matching the document-uri() >> for $doc in basex:db('yourdb') >> where matches(document-uri($doc),'test.xml') >> return $doc > Please note that the document-uri() function only evaluates document-nodes, to test against inner nodes you should use > base-uri($node) instead of document-uri(): > >> for $node in basex:db('yourdb')//child >> where matches(base-uri($node),'test.xml') >> return $node > > As there is no standardized way of handling collections of XML documents we are still looking forward to feedback regarding this issue. > > Hope this helps, feel free to ask more otherwise. > > Kind regards > Michael > > Am 29.07.2010 um 16:29 schrieb cosmotron+basex at gmail.com: > >> If I add two documents to a BaseX DB, let's say normal.xml and normal2.xml, is there a way to refer to each one individually? >> >> I know about the doc() function, but it looks at the filesystem for their location, rather than in the database itself. >> >> For instance, if I query with this: doc("normal.xml")/name , then I will get an error about normal.xml not being found. >> >> I also tried: basex:db("my-db-name")/doc("normal.xml")/name and received the same error. >> >> Thanks for any help! >> >> _______________________________________________ >> BaseX-Talk mailing list >> BaseX-Talk at mailman.uni-konstanz.de >> https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk > >
RL
Hey,
Thanks for the quick reply!
I decided to do a simple query using basex:db(), and its results are... odd. Simply performing:
for $doc in basex:db('yourdb')
return $doconly returns the first document in my database. I thought maybe the database was corrupt or something, so I tried:
for $doc in /my_root_node
return $docAnd that returned the entire structure of all documents in the database.
Is that the normal functionality of basex:db()? If so, then I can not iterate through it as per your examples, since it will only see the first document.
--
Ryan Lewis '09
Clarkson University
Quoted text · Michael Seiferle · 53 lines
On Thu, Jul 29, 2010 at 10:42 AM, Michael Seiferle < michael.seiferle at uni-konstanz.de> wrote: > Hi there, > > the most convenient way to identify documents inside collections might be > restricting the the query to a single document or a group of documents via > matching the document-uri() > > for $doc in basex:db('yourdb') > where matches(document-uri($doc),'test.xml') > return $doc > > Please note that the document-uri() function only evaluates document-nodes, > to test against inner nodes you should use > base-uri($node) instead of document-uri(): > > for $node in basex:db('yourdb')//child > where matches(base-uri($node),'test.xml') > > return $node > > > As there is no standardized way of handling collections of XML documents we > are still looking forward to feedback regarding this issue. > > Hope this helps, feel free to ask more otherwise. > > Kind regards > Michael > > Am 29.07.2010 um 16:29 schrieb cosmotron+basex at gmail.com: > > If I add two documents to a BaseX DB, let's say normal.xml and normal2.xml, > is there a way to refer to each one individually? > > I know about the doc() function, but it looks at the filesystem for their > location, rather than in the database itself. > > For instance, if I query with this: doc("normal.xml")/name , then I will > get an error about normal.xml not being found. > > I also tried: basex:db("my-db-name")/doc("normal.xml")/name and received > the same error. > > Thanks for any help! > > _______________________________________________ > BaseX-Talk mailing list > BaseX-Talk at mailman.uni-konstanz.de > https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk > > >
RL
Awesome, that works perfectly, thanks!
I do have a question though. How come one must use a loop in order to access elements in this way? It seems like the names of the documents in a database would be a sort of key that would allow constant time look ups, being that they must be unique. Especially since the hierarchy is there conceptually: database -> document -> root node -> children, so it's strange that something like: collection("db")/document("document-name")/root/child is not possible.
--
Ryan Lewis '09
Clarkson University
Quoted text · Michael Seiferle · 92 lines
On Thu, Jul 29, 2010 at 11:42 AM, Michael Seiferle < michael.seiferle at uni-konstanz.de> wrote: > Hi Ryan, > sorry for misleading you, I was tricked by our commands myself. > Instead of basex:db('name') which opens the DB as a database (thus the > first document is added to the context) please use the collection('name') > command: > > for $doc in collection('test') > > return $doc > Sorry for the inconvenience, the hint on using matches(document-uri(... > should work correctly now. > If you have any further questions feel free to ask. > Kind regards > Michael > > > Am 29.07.2010 um 16:57 schrieb Ryan Lewis: > > > Hey, > > > > Thanks for the quick reply! > > > > I decided to do a simple query using basex:db(), and its results are... > odd. Simply performing: > >> for $doc in basex:db('yourdb') > >> return $doc > > only returns the first document in my database. I thought maybe the > database was corrupt or something, so I tried: > >> for $doc in /my_root_node > >> return $doc > > And that returned the entire structure of all documents in the database. > > > > Is that the normal functionality of basex:db()? If so, then I can not > iterate through it as per your examples, since it will only see the first > document. > > > > -- > > Ryan Lewis '09 > > Clarkson University > > > > > > On Thu, Jul 29, 2010 at 10:42 AM, Michael Seiferle < > michael.seiferle at uni-konstanz.de> wrote: > > Hi there, > > > > the most convenient way to identify documents inside collections might be > restricting the the query to a single document or a group of documents via > matching the document-uri() > >> for $doc in basex:db('yourdb') > >> where matches(document-uri($doc),'test.xml') > >> return $doc > > Please note that the document-uri() function only evaluates > document-nodes, to test against inner nodes you should use > > base-uri($node) instead of document-uri(): > > > >> for $node in basex:db('yourdb')//child > >> where matches(base-uri($node),'test.xml') > >> return $node > > > > As there is no standardized way of handling collections of XML documents > we are still looking forward to feedback regarding this issue. > > > > Hope this helps, feel free to ask more otherwise. > > > > Kind regards > > Michael > > > > Am 29.07.2010 um 16:29 schrieb cosmotron+basex at gmail.com<cosmotron%2Bbasex at gmail.com> > : > > > >> If I add two documents to a BaseX DB, let's say normal.xml and > normal2.xml, is there a way to refer to each one individually? > >> > >> I know about the doc() function, but it looks at the filesystem for > their location, rather than in the database itself. > >> > >> For instance, if I query with this: doc("normal.xml")/name , then I will > get an error about normal.xml not being found. > >> > >> I also tried: basex:db("my-db-name")/doc("normal.xml")/name and received > the same error. > >> > >> Thanks for any help! > >> > >> _______________________________________________ > >> BaseX-Talk mailing list > >> BaseX-Talk at mailman.uni-konstanz.de > >> https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk > > > > > >
MS
Hi Ryan,
(this time CC to the list...)
Quoted text · Michael Seiferle · 2 lines
Am 29.07.2010 um 18:29 schrieb Ryan Lewis: > Awesome, that works perfectly, thanks!
great, glad I could help!
Quoted text · Michael Seiferle · 2 lines
> > I do have a question though. How come one must use a loop in order to access elements in this way? It seems like the names of the documents in a database would be a sort of key that would allow constant time look ups, being that they must be unique. Especially since the hierarchy is there conceptually: database -> document -> root node -> children, so it's strange that something like: collection("db")/document("document-name")/root/child is not possible.
This is due to the XQuery data model [1]. XQuery has no formal notion of files inside a database/collection (Christian might correct me if I am wrong), so the collection() command returns any sequence of (document-)nodes for the given database. It is up to the user to pick those nodes he wants to process.
We are currently looking for ideas on navigating collections more intuitively; something similar to "collection('db/path-to/document.xml')" that should still conform to the current W3C recommendation. As the subsequent document-uri() usually works well enough this is not too high on our priority list.
Hope I could help to clear things up, feedback is welcome.
Kind regards
Michael
[1] http://www.w3.org/TR/xquery/#id-input-sources
Quoted text · Michael Seiferle · 80 lines
> > -- > Ryan Lewis '09 > Clarkson University > > > On Thu, Jul 29, 2010 at 11:42 AM, Michael Seiferle <michael.seiferle at uni-konstanz.de> wrote: > Hi Ryan, > sorry for misleading you, I was tricked by our commands myself. > Instead of basex:db('name') which opens the DB as a database (thus the first document is added to the context) please use the collection('name') command: >> for $doc in collection('test') >> return $doc > Sorry for the inconvenience, the hint on using matches(document-uri(... should work correctly now. > If you have any further questions feel free to ask. > Kind regards > Michael > > > Am 29.07.2010 um 16:57 schrieb Ryan Lewis: > >> Hey, >> >> Thanks for the quick reply! >> >> I decided to do a simple query using basex:db(), and its results are... odd. Simply performing: >>> for $doc in basex:db('yourdb') >>> return $doc >> only returns the first document in my database. I thought maybe the database was corrupt or something, so I tried: >>> for $doc in /my_root_node >>> return $doc >> And that returned the entire structure of all documents in the database. >> >> Is that the normal functionality of basex:db()? If so, then I can not iterate through it as per your examples, since it will only see the first document. >> >> -- >> Ryan Lewis '09 >> Clarkson University >> >> >> On Thu, Jul 29, 2010 at 10:42 AM, Michael Seiferle <michael.seiferle at uni-konstanz.de> wrote: >> Hi there, >> >> the most convenient way to identify documents inside collections might be restricting the the query to a single document or a group of documents via matching the document-uri() >>> for $doc in basex:db('yourdb') >>> where matches(document-uri($doc),'test.xml') >>> return $doc >> Please note that the document-uri() function only evaluates document-nodes, to test against inner nodes you should use >> base-uri($node) instead of document-uri(): >> >>> for $node in basex:db('yourdb')//child >>> where matches(base-uri($node),'test.xml') >>> return $node >> >> As there is no standardized way of handling collections of XML documents we are still looking forward to feedback regarding this issue. >> >> Hope this helps, feel free to ask more otherwise. >> >> Kind regards >> Michael >> >> Am 29.07.2010 um 16:29 schrieb cosmotron+basex at gmail.com: >> >>> If I add two documents to a BaseX DB, let's say normal.xml and normal2.xml, is there a way to refer to each one individually? >>> >>> I know about the doc() function, but it looks at the filesystem for their location, rather than in the database itself. >>> >>> For instance, if I query with this: doc("normal.xml")/name , then I will get an error about normal.xml not being found. >>> >>> I also tried: basex:db("my-db-name")/doc("normal.xml")/name and received the same error. >>> >>> Thanks for any help! >>> >>> _______________________________________________ >>> BaseX-Talk mailing list >>> BaseX-Talk at mailman.uni-konstanz.de >>> https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk >> >> > >
Written for BaseX 6. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery