XQuery/Saving and Updating Data

From Wikibooks, open books for an open world
Jump to: navigation, search

Motivation[edit]

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.

Method[edit]

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 file[edit]

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 file[edit]

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