The primitives are insert node (into, as first into, before, after), delete node, replace node, replace value of node and rename node. On a database they change the data; on a file, update a copy with copy ... modify ... return. Run basex -i booknest-catalog.xml restock.xq:
(: XQUF on a copy: the stored catalog is not touched :)
copy $b := //book[@id = "b3"]
modify (
replace value of node $b/supply/availability with "in-stock",
replace value of node $b/supply/price with "26.00",
insert node <format>hardcover</format> after $b/pages,
delete node $b/summary,
rename node $b/rating as "stars"
)
return $b/(*[position() = 5 to 8], .//price)Output
<pages>256</pages> <format>hardcover</format> <published>2023</published> <stars>4.8</stars> <price currency="USD">26.00</price>
Select new elements by position: count($b/format) gave 0 on BaseX 12.4 693,830 , answered from the source's index.
XQUF
XQuery Update Facility (XQUF) is an extension to XQuery for updating XML documents in place, via insert, delete, replace, and rename expressions, a copy-modify-return transform expression, and an inline update expression usable inside a FLWOR. BaseX 693,830 is a program that supports XQUF.Each example below updates the following document independently:
merged-01-01-ch05-xquf-data.xml
<?xml version="1.0" encoding="UTF-8" ?>
<a>
<b>Hello</b>
<b>World</b>
</a>
insert node
The insert node expression adds one or more nodes into, before, or after a target node. Inserting a sequence of an attribute, a text node, and an element into /a appends them as the last children (attributes are added to the element regardless of position):insert node (attribute {'id'}{5},'Yes!',<c/>) into /a
Output
insert node <c/> as first into /a
(: 'as last into' can be used too :)
Output
<a> <c/> <b>Hello</b> <b>World</b> </a>
insert node <c/> before /a/b[2]
(: 'after' can be used too :)
Output
<a> <b>Hello</b> <c/> <b>World</b> </a>
delete node
Removes one or more target nodes from the document:delete node (a/b[1],a/b[2])
Output
<a/>
replace node
Replaces a target node with a new node, including its name and content:replace node a/b[2] with <c>Kitty</c>
Output
<a> <b>Hello</b> <c>Kitty</c> </a>
replace value of node a/b[2] with <c>Kitty</c>
Output
<a> <b>Hello</b> <b>Kitty</b> </a>
rename node
Changes the name of a target node, keeping its content:rename node a/b[1] as 'x'
Output
<a> <x>Hello</x> <b>World</b> </a>
transform expression: copy ... modify ... return
A copy-modify-return expression binds a variable to a copy of a node, applies a sequence of update expressions to that copy inside modify, and returns the modified copy without touching the original document:copy $v := /a
modify (
rename node $v/b[1] as 'c',
insert node ('Kitty') into $v/b[2]
) return $v
Output
<a> <c>Hello</c> <b>WorldKitty</b> </a>
update expression
An update expression applies update expressions to a node inline, e.g. within the return clause of a for, without a separate copy-modify-return block:for $v in a/b
return $v update delete node text()
Output
<b/> <b/>