XQuery Update Tutorial
XQuery Update∞ is the update extension language for XQuery, specified by the W3C XQuery Working Group. The specification is currently a Last Call Working Draft (28 August 2007).
This tutorial aims to quickly get the reader up to speed on the basics of using XQuery Update by describing syntax, semantics, and common gotchas. Links are provided back to the XQuery Update specification, to allow readers to look more thoroughly into the topics discussed.
XQuery Update Fundamentals
- XQuery Update doesn't perform any of the updates until after the query. Updates are kept on what is called a Pending Update List∞ during the query. For instance this means you can't update the value of a node and then read that value expecting it to be the new version - it won't be.
- This means that it's irrelevant which order updates appear in the query. Updates can clash by affecting the same node(s) in different ways - this is resolved∞ by either throwing an exception (and performing no updates), or by applying the updates in an order defined by the specification.
- You can't mix updating and non-updating expressions. For instance, if one argument to the "," operator (concatenation)∞ is updating, they all have to be. Two expressions are exceptions - the "fn:error()" function and "()" (the empty sequence) both count as either updating or non-updating expressions.
XQuery Update Syntax
Inserting children
reference∞
insert nodes <a><b/></a> into doc("foo")//c[@id = 5]
insert nodes /a/b as first into //c[@id = 3]
insert nodes /a/node() as last into /a/b
The result of the target expression (the one after "into") must be a single element or document node. The "insert ... into ..." variant does not guarantee the position the new children will be inserted into - which can allow the implementation to be more efficient.
The result of the source expression (the one after "nodes") is converted into a sequence of nodes. Nodes in the source expression are copied, and atomic items are concatenated with spaces between them and are turned into a text node.
If attributes are inserted, the target must be an element. Order is not significant for attributes, so they can be inserted anyway.
- NB In all updating expressions that use the keyword "nodes", this keyword can be freely interchanged with the non-plural "node". No semantic significance is placed on which keyword is used.
Inserting before/after
reference∞
insert nodes /a/b after //c[@id = 5]/comment()
insert nodes /a/b before //c[@id = 5]/text()[1]
The result of the target expression must be a single element, comment, processing-instruction or text node, and it must have a parent node.
The result of the source expression (the one after "nodes") is converted into a sequence of nodes. Nodes in the source expression are copied, and atomic items are concatenated with spaces between them and are turned into a text node.
If attributes are inserted, the parent node must be an element. Order is not significant for attributes, so they can be inserted anyway.
Deleting nodes
reference∞
delete nodes /a/b//node()
Replacing a node, or it's value
reference∞
replace node //c[@id = 5] with "foo"
replace value of node //c[@id = 5] with "foo"
The result of the target expression must be a single element, attribute, comment, processing-instruction or text node, and it must have a parent node.
If "replace node" is used, the result of the source expression (the one after "nodes") is converted into a sequence of nodes. Nodes in the source expression are copied, and atomic items are concatenated with spaces between them and are turned into a text node.
Only attributes can replace attributes, and attributes cannot be used to replace a non-attribute.
If "replace value of node" is used, the result of the source expression is converted into a string by atomizing the sequence, then concatenating the resulting atomic items with spaces between them.
Renaming a node
reference∞
rename node //c[@id = 5] as "fifth_c"
The result of the target expression must be a single element, attribute or processing-instruction node.
Updating function
reference∞
A function needs to be declared as "updating" if will perform an update, like this:
declare updating function local:myUpdate($elem as element())
{
rename node $elem as "new_name"
};
An updating function must not declare a return type.
The transform expression
reference∞
There is a way to apply updates and see the results in the same query - this is called a transform expression. A transform expression is
not an updating expression - it works by first copying nodes, then applying the updates to the copy of the nodes.
copy $c := //c[@id = 5]
modify (
delete $c/a/b,
rename $c as "not_c"
)
return $c
This can be very useful for formatting and transforming results before they are returned by a query.
CategoryXQuery
There are no comments on this page. [Add comment]