2

I am very new to XML document database technologies, Xquery/Xpath and so on. So this is probably a very newbie question.

Scenario: A number of XML documents as the input, want to run some number of transformations can be run on these XML documents (using XQuery). I'd like to store these results. Into the same XML data store as the input.

So far I am experimenting with using the BaseX document database to store and processes these XML documents, and so far its been very easy to work with, I am impressed.

Ideally I'd like to interface with BaseX using the XQJ API (http://xqj.net/basex/) as my reasoning would be that XQJ would keep the implementation of application code independent of BaseX as can be. The secondary option would write my java code directly to the BaseX API.

The Problem: I am having a hard time figuring out how to store the results from an XQuery as a new "document" in the database. Perhaps this is more of a conceptual lack of understanding with XQuery (or XQuery Update) itself than any difficulty with the BaseX/XQJ API.

In this simple example if I have a query like this, it returns some XML output with in a format that I want for my new document

let $items := //firstName
return <results>
   { for $item in $items
     return <result> {$item} </result>
   }
   </results>

Gives

<results>
  <result>
    <firstName>Bob</firstName>
  </result>
  <result>
    <firstName>Joe</firstName>
  </result>
  <result>
    <firstName>Tom</firstName>
  </result>
</results>

I want to store this new <result> document back into the database, for use in later querying/transformations/etc. In SQL this makes sense to me. I would do CREATE TABLE <name> SELECT <query> or INSERT INTO, etc. But I am unclear what the equivalent is in XQuery. I think the XQuery Update functionality is what I need here, but I'm having trouble finding concrete examples.

This is further complicated when dealing with XQJ

XQResultSequence rs = xqe.executeQuery("//firstName");
// what do i do with it now??

Is there a way to persist this XQResultSequence back INTO the database using BaseX? Or even better, can I run additional XQueries directly on the XQResultSequence?

Thanks for the help!

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
barab157
  • 111
  • 1
  • 4

1 Answers1

2

BaseX implements XQuery Update Facility, so you should be able to use fn:put:

let $items := //firstName
return fn:put(
   <results>{ 
     for $item in $items
     return <result> {$item} </result>
   }</results>, 
  "/results/result-new.xml")

If you are running simple ad-hoc queries like above, it should be fairly straightforward. I'm not very familiar with XQJ, but if you want to run queries in a sequence, I suspect there is a way to pass those XQResultSequence variables back to a new query, in which you would likely accept it by declaring a variable as external in the following query:

declare variable $previous-result as item()* external;
wst
  • 11,681
  • 1
  • 24
  • 39
  • Thanks, using 'fn:put' sort of does the job for me. At least I can then get an *.xml file output, but it looks like I'll have to then import the resulting file back into to the database for further processing. Is there a way to skip that intermediate step? – barab157 Jan 15 '16 at 21:51
  • I think I've found a good solution using the BaseX java client example `String results = session.execute("xquery " + QUERY_STRING); session.add("results/results.xml", new ByteArrayInputStream(results.getBytes()));` – barab157 Jan 15 '16 at 22:24
  • 1
    @barab157 What I was going to suggest is simply doing everything you need in one query. This is a matter of preference, but I think the clean separation from database and middleware makes applications more maintainable and performant. But if you found a nice way to do it in Java, please go ahead and post your answer here. – wst Jan 15 '16 at 22:28