Last modified on 28 February 2012, at 15:03

XQuery/Saving and Updating Data

MotivationEdit

You have some web forms (such as XForms) that need to save their data to your database. You want a single XQuery that will be used to save new data and update existing data. If a form is used to update an existing record, you can assume that it has an <id> tag in the XML document being saved. New documents will need to have a new document id created for them.

MethodEdit

We use HTTP POST data and scan for a specific element like id. If the record does not have an id element, we know that we must create a new record. Note that there is no sequence number generated in this example yet. If there is an id parameter, we will delete the old file and save the new data into the same file. Note that there is no backup or archive.

Sample Program to Store/Remove a single XML fileEdit

xquery version "1.0";
declare namespace exist = "http://exist.sourceforge.net/NS/exist"; 
declare namespace request="http://exist-db.org/xquery/request";
declare namespace xmldb="http://exist-db.org/xquery/xmldb";
 
declare option exist:serialize "method=xhtml media-type=text/xml indent=yes";
 
(: Call this like this:
For new records:
http://localhost:8080/exist/rest/db/xquery-examples/save-test/new-update-save.xq?new=true
 
For updates where each record has an id:
http://localhost:8080/exist/rest/db/xquery-examples/save-test/new-update-save.xq?id=123
:)
 
(: replace this with your document, for example use request:get-data() :)
let $my-doc := 
<data>
   <id>123</id>
   <message>Hello World</message>
</data>
 
 
let $id := $my-doc/id
 
let $collection := 'xmldb:exist:///db/xquery-examples/save-test'
 
(: this logs you in; you can also get these variables from your session variables :)
let $login := xmldb:login($collection, 'mylogin', 'my-password')
 
 
(: replace this with a unique file name with a sequence number :)
let $file-name := 'test-save.xml'
 
return
if (not($id))
       then (
       let $store-return-status := xmldb:store($collection, $file-name, $my-doc)
             return
                <message>New Document Created {$store-return-status} at {$collection}/{$file-name}</message>
       )
       else (
           let $remove-return-status := xmldb:remove($collection, $file-name)
           let $store-return-status := xmldb:store($collection, $file-name, $my-doc)
           return
                <message>Document {$id} has been successfully updated</message>)
    }</results>

Sample Program to Insert an XML item at the end of an XML fileEdit

Sometimes you do not want to create a new XML file, but only save the results at the end of an existing XML file. This can be done using the XQuery update operations.

W3C Candidate Recommendation for XQuery Update Operations

eXist 1.2/1.3/1.4/1.5 syntax for XQuery Update Operations

For example, in eXist 1.2/1.3/1.4 the operation syntax is the following:

     let $append-result := update insert <item/> into doc("myfile.xml")/items