<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: update_ext.xml 17822 2012-12-10 23:18:20Z joewiz $ --><book><bookinfo><productname>eXist-db – Open Source Native XML Database</productname><title>XQuery Update Extension</title><date>December 2012</date></bookinfo><chapter><title>XQuery Update Extension</title><section id="intro"><title>Introduction</title><para>eXist-db provides an extension to XQuery for updating nodes in the database. The
                extension makes the following operations possible using a simple syntax: insert,
                delete, replace, update value, and rename.</para></section><section id="considerations"><title>Important Considerations</title><section id="w3c-rec"><title>Relationship to W3C Recommendation</title><para>This extension was created well before the W3C working group created the
                        <ulink url="http://www.w3.org/TR/xquery-update-10/">XQuery Update Facility
                        1.0</ulink> recommendation, and it differs substantially from the
                    recommendation. However, it remains perfectly functional and is still the
                    primary method (besides <ulink url="http://xmldb-org.sourceforge.net/xupdate/">XUpdate</ulink>) for updating nodes.</para></section><section id="persistence"><title>Persistent Document Updates</title><para>The XQuery update extension has been designed around updating
                        <emphasis>persistent</emphasis> documents stored in the database. It is not
                    suitable for updating temporary document fragments constructed within an query,
                    i.e., you can't use it to modify the results returned by a query. For example,
                    the following query has no visible effect because it operates on an XML node
                    constructed in-memory: </para><synopsis language="xquery">let $node := &lt;root&gt;&lt;a/&gt;&lt;/root&gt;
return 
    update insert &lt;b/&gt; into $node/a
</synopsis><para>Since $node is an in-memory constructed element, rather than a node stored in
                    the database, the query has no effect and simply returns the empty
                    element.</para></section></section><section id="syntax"><title>Update Syntax</title><para>All update statements start with the keyword "update", followed by an update
                action. Available actions are: "insert", "delete", "replace", "value" and "rename".
                The return type of the expression is <option>empty()</option>. </para><para>An update statement may occur at any position within the XQuery main code or a
                function body. </para><warning><para>When using an update within the return clause of a FLWOR expression, be
                    cautious when deleting or replacing nodes that are still being used by enclosing
                    code. This is because a delete or replace will be processed immediately, and the
                    deleted or replaced node will no longer be available to the query. Such actions
                    can corrupt the database. For example, the following expression will throw the
                    database into an inconsistent state if //address returns more than one
                    node:</para><example><title>An unsafe update</title><programlisting language="xquery">
for $address in //address
return
    update delete //address
</programlisting></example><para>However, an expression like the following is safe as it only modifies the
                    current iteration variable (note that the following example deletes $address
                    (the current iteration variable) rather than //address (all addresses in the
                    database, including others that have not been deleted yet):</para><example><title>A safe update</title><programlisting language="xquery">
for $address in //address
return
    update delete $address
</programlisting></example><para>Aside from this caveat, eXist-db's XQuery update extension is safe to
                    use.</para></warning><section id="insert"><title>Insert</title><synopsis>update insert expr ( into | following | preceding )
                exprSingle</synopsis><para>Inserts the content sequence specified in expr into the element node passed
                    via exprSingle. exprSingle and expr should evaluate to a node set. If exprSingle
                    contains more than one element node, the modification will be applied to each of
                    the nodes. The position of the insertion is determined by the keywords "into",
                    "following" or "preceding":</para><variablelist><varlistentry><term>into</term><listitem><para>The content is appended after the last child node of the specified
                                elements.</para></listitem></varlistentry><varlistentry><term>following</term><listitem><para>The content is inserted immediately after the node specified in
                                exprSingle.</para></listitem></varlistentry><varlistentry><term>preceding</term><listitem><para>The content is inserted before the node specified in
                                exprSingle.</para></listitem></varlistentry></variablelist><example><title>Insert Example: Element</title><programlisting language="xquery">
update insert &lt;email type="office"&gt;andrew@gmail.com&lt;/email&gt; into //address[fname="Andrew"]
</programlisting></example><example><title>Insert Example: Attribute</title><programlisting language="xquery">
update insert attribute type {'permanent'} into //address[fname="Andrew"]
</programlisting></example></section><section id="replace"><title>Replace</title><synopsis>update replace expr with exprSingle</synopsis><para>Replaces the nodes returned by expr with the nodes in exprSingle. expr may
                    evaluate to a single element, attribute or text node. If it is an element,
                    exprSingle should contain a single element node as well. If it is an attribute
                    or text node, the value of the attribute or the text node is set to the
                    concatenated string values of all nodes in exprSingle. expr cannot be the root
                    element of a document.</para><example><title>Replace Example</title><programlisting language="xquery">update replace //fname[. = "Andrew"] with &lt;fname&gt;Andy&lt;/fname&gt;</programlisting></example></section><section id="value"><title>Value</title><synopsis>update value expr with exprSingle</synopsis><para>Updates the content of all nodes in expr with the items in exprSingle. If expr
                    is an attribute or text node, its value will be set to the concatenated string
                    value of all items in exprSingle.</para><example><title>Value Example</title><programlisting language="xquery">update value //fname[. = "Andrew"] with 'Andy'</programlisting></example></section><section id="delete"><title>Delete</title><synopsis>update delete expr</synopsis><para>Removes all nodes in expr from their document. expr cannot be the root element
                    of a document.</para><example><title>Delete Example</title><programlisting language="xquery">
for $city in //address/city 
return
    update delete $city
</programlisting></example></section><section id="rename"><title>Rename</title><synopsis>update rename expr as exprSingle</synopsis><para>Renames the nodes in expr using the string value of the first item in
                    exprSingle as the new name of the node. expr should evaluate to a set of
                    elements or attributes. expr cannot be the root element of a document.</para><example><title>Rename Example</title><programlisting language="xquery">
for $city in //address/city 
return
    update rename $city as 'locale'
</programlisting></example></section></section></chapter></book>