Update Primitives
...
Example 1: in a document doc.xml
, rename all elements children of a CATEGORY as CATEGORY_NAME
:
Anchor | ||||
---|---|---|---|---|
|
Code Block | ||
---|---|---|
| ||
for $name in doc("doc.xml")//CATEGORY/NAME (: selection :) return rename node $name as CATEGORY_NAME (: update :) |
Example 2: for all BOOK elements which have an attribute Id, replace that attribute with a child ID in first position:
Code Block | ||
---|---|---|
| ||
for $idattr in doc("data.xml")//BOOK/@Id (: selection :) return ( delete node $idattr, (: update 1 :) insert node <ID>{string($idattr)}</ID> (: update 2 :) as first into $idattr/.. ) |
...
Direct update of an XML database:
In the examples in the previous topic, nodes belonging to a database are selected then updated.
Info Note
The XQUF notion of a database is very general: it means any collection of XML documents or well-formed fragments (trees).
XQuery Update does not define precisely the protocol by which updating operations are applied to a database. This is left to implementations. For example transaction and isolation issues are not addressed by the specifications.
It is simply assumed that updates are applied to the database when the execution of a script completes. The language is designed in such a way that semantics of the "apply-updates" operation are precisely defined, yet as much space as possible is left for optimization by database implementations.
Points to be noticed:
Updates are not applied immediately as the updating expression executes. Instead they are accumulated into a "Pending Update List". At some point at the end of the execution, Pending Updates are applied all at once, and the database is updated atomically.
A noticeable consequence is that updates are not visible during the script execution, but only after. This can be fairly off-putting for a developer. It also has a definite influence on programming style. We will see later examples of this effect and how to cope with it.
The same expression can update several documents at once. The examples above could be applied to any collection of documents instead of the single document doc.xml. Example:
Code Block language xml for $name in collection("/allbooks")//CATEGORY/NAME return rename node $name as CATEGORY_NAME
Transforms without side effects:
The XQUF has a supplementary operation called transform which updates a copy of an existing node, without modifying the original, and returns the transformed tree.
The following example produces a transformed version of doc.xml without actually touching the original document:
Code Block language xml copy $d := doc("doc.xml") modify ( for $n in $d//CATEGORY/NAME return rename node $n as CATEGORY_NAME ) return $d
Notice that within the modify clause, XQUF forbids modifying the original version of copied trees (here the document doc.xml itself); only the copied trees can be modified.
The following expression would cause an error:Code Block language xml copy $d := doc("doc.xml") modify ( for $n in doc("doc.xml")//CATEGORY/NAME(: *** wrong *** :) return rename node $n as CATEGORY_NAME ) return $d