Difference between revisions of "XQuery Update"

From BaseX Documentation
Jump to navigation Jump to search
m ("b" tag was not being rendered, and escaping the left angle bracket seems to fix the problem)
 
(237 intermediate revisions by 11 users not shown)
Line 1: Line 1:
With the release of version 6.0, BaseX offers a complete implementation of the [http://www.w3.org/TR/xquery-update-10/ XQuery Update Facility (XQUF)].
+
This article is part of the [[XQuery|XQuery Portal]].
 +
It summarizes the update features of BaseX.
  
==Introduction==
+
BaseX offers a complete implementation of the [https://www.w3.org/TR/xquery-update-10/ XQuery Update Facility (XQUF)]. This article aims to provide a quick and basic introduction to XQUF. First, some examples for update expressions are given. Next, the challenges are addressed that arise due to the functional semantics of the language.
This article aims to provide a very quick and basic introduction to the XQUF. First are some examples for new expressions and useful information on each of them.
 
After that a few problems are solved that arise frequently, due to the special nature of the language. These are stated in the [[Update#XQUF Concepts|Concepts]] section.
 
  
==New Functionality==
+
=Features=
  
===Updating Expressions===
+
==Updating Expressions==
There are five new expressions to modify data. While insert, delete, rename and replace basically explain themselves, the transform expression is different. Modified nodes are copied in advance and the original databases remain untouched.
 
  
An expression consists of a target node (the node we want to alter) and additional information like insertion nodes, a QName, etc. which depends on the type of expression. You can find a few examples and additional information below.
+
There are five new expressions to modify data. While {{Code|insert}}, {{Code|delete}}, {{Code|rename}} and {{Code|replace}} are basically self-explanatory, the {{Code|transform}} expression is different, as modified nodes are copied in advance and the original databases remain untouched.
====insert====
 
====delete====
 
====replace====
 
====rename====
 
  
===Non-Updating Expressions===
+
An expression consists of one or more target nodes (the nodes we want to alter) and (depending on the expression type) additional information like nodes to be inserted, a QName, etc., and optional modifiers. You can find a few examples and additional information below.
====transform====
 
  
===Functions===
+
===insert===
  
====fn:put()====
+
<pre lang='xquery'>
FN:put() is also part of the XQUF and enables the user to serialize XDM instances to secondary storage. It is executed at the end of a snapshot. Serialized documents therefore reflect all changes made effective during a query.
+
insert node (attribute { 'a' } { 5 }, 'text', <e/>) into /n
 +
</pre>
  
==XQUF Concepts==
+
Insert enables you to insert a sequence of nodes into a single target node. Several modifiers are available to specify the exact insert location: insert into '''as first'''/'''as last''', insert '''before'''/'''after''' and insert '''into'''.
There are a few specialties around XQuery Update that you should know about. In addition to the <b>simple expression</b>, the XQUF adds the <b>updating expression</b> as a new type of expression. An updating expression returns only a PUL as a result which is subsequently applied to addressed databases and DOM nodes. A simple expression cannot perform any permanent changes and returns an empty or non-empty sequence.
 
  
===Pending Update List===
+
''Note'': in most cases, '''as last''' and '''after''' are evaluated faster than '''as first''' and '''before'''.
The most important thing to keep in mind when using XQuery Update is the Pending Update List (PUL). Updating statements are not executed immediately, but are first collected as update primitives within a set-like structure, the PUL. At the end of a query, all update primitives on this list are applied after being checked for compatibility. If a conflict exists, an error message is returned and all accessed databases remain untouched (atomicity). For the user this means updates are only visible <b>after</b> the end of a snapshot. This is closely connected to the way you can access query results. There's a section dedicated to this issue.
 
  
===Returning Results===
+
===delete===
It is not possible to mix different types of expressions in a query result. The outermost expression of a query must either be a collection of updating or non-updating expressions. Generally there is no way to perform any updating queries and return a result at the same time as you cannot access your own changes during a single query. Regarding database nodes, you can update your nodes within the first query and access modifications in subsequent queries.
 
  
But trying to modify and return a DOM node within the same snapshot is another story. As changes on DOM nodes are non-persistent, you cannot access them in a subsequent query. This is where the transform expression comes into play.
+
<pre lang='xquery'>
 +
delete node //n
 +
</pre>
  
===Function Declaration===
+
The example query deletes all <code><n></code> elements in your database. In contrast to other updating expressions, multiple nodes can be supplied as a target.
To use updating expressions within a function, the 'updating' flag has to be added to the function declaration. A correct declaration of a function that contains updating expressions (or a function that calls updating functions) looks like this: declare <b>updating</b> function { ... }
 
  
==Effects on Your Documents==  
+
===replace===
In BaseX, all updates are performed on database nodes. This is why update operations
+
 
never affect the original input file. You can, however, use the [[Commands|EXPORT]] command or the fn:put() function to create an updated XML file. Activating the WRITEBACK property ([[Commands|SET Command]]) directly propagates changes of your database to the original input file. Make sure you back up your data in advance, as this approach modifies the underlying XML file.
+
<pre lang='xquery'>
 +
replace node /n with <a/>
 +
</pre>
 +
 
 +
The target element is replaced by the DOM node <code><a/></code>. You can also replace the value of a node and its descendants by using the modifier '''value of''':
 +
 
 +
<pre lang='xquery'>
 +
replace value of node /n with 'newValue'
 +
</pre>
 +
 
 +
All descendants of /n are deleted, and the supplied text is inserted as the only child. The result of the insert sequence is either a single text node or an empty sequence. If the insert sequence is empty, all descendants of the target are deleted. Consequently, replacing the value of a node leaves the target with either a single text node or no descendants at all.
 +
 
 +
===rename===
 +
 
 +
<pre lang='xquery'>
 +
for $n in //originalNode
 +
return rename node $n as 'renamedNode'
 +
</pre>
 +
 
 +
All <code>originalNode</code> elements are renamed. A loop can be used to modify multiple nodes within a single statement. Nodes on the {{Code|descendant}} or {{Code|attribute}} axis of the target are not affected.
 +
 
 +
==Main-Memory Updates==
 +
 
 +
With the following expressions, copies of nodes are created, which can then be modified with the already presented updating expressions. As the original node will not be changed, the expressions are called ''non-updating''.
 +
 
 +
===copy/modify/return===
 +
 
 +
<pre lang='xquery'>
 +
copy $c := doc('example.xml')//originalNode
 +
modify rename node $c as 'copyOfNode'
 +
return $c
 +
</pre>
 +
 
 +
A copy of the {{Code|originalNode}} element is created, renamed and returned; the original document will not be updated.
 +
 
 +
In the following example, multiple update operations are performed on the copied node:
 +
 
 +
;Query:
 +
 
 +
<pre lang='xquery'>
 +
copy $c :=
 +
  <entry>
 +
    <title>Transform expression example</title>
 +
    <author>BaseX Team</author>
 +
  </entry>
 +
modify (
 +
  replace value of node $c/author with 'BaseX',
 +
  replace value of node $c/title with concat('Copy of: ', $c/title),
 +
  insert node <author>Joey</author> into $c
 +
)
 +
return $c
 +
</pre>
 +
 
 +
;Result:
 +
 
 +
<pre lang="xml">
 +
<entry>
 +
  <title>Copy of: Transform expression example</title>
 +
  <author>BaseX</author>
 +
  <author>Joey</author>
 +
</entry>
 +
</pre>
 +
 
 +
Instead of the main-memory {{Code|<entry>}} element, a database node can be supplied:
 +
 
 +
<pre lang='xquery'>
 +
copy $c := (db:get('example')//entry)[1]
 +
...
 +
</pre>
 +
 
 +
In this case, the database node remains untouched, as all updates are performed on the node copy.
 +
 
 +
Entire documents can be copied and modified:
 +
 
 +
<pre lang='xquery'>
 +
copy $doc := doc("zaokeng.kml")
 +
modify (
 +
  for $point in $doc//*:Point
 +
  return insert node (
 +
    <extrude>1</extrude>,
 +
    <altitudeMode>relativeToGround</altitudeMode>
 +
  )  before $point/*:coordinates
 +
)
 +
return $doc
 +
</pre>
 +
 
 +
===update===
 +
 
 +
The {{Code|update}} expression is a BaseX-specific convenience operator for the bulky {{Code|copy/modify/return}} construct. Similar to the [[XQuery 3.0#Simple Map Operator|XQuery 3.0 map operator]], the nodes resulting from the first expression are bound as context items, and the bracketed expressions performs updates on the item. The updated nodes is returned as result:
 +
 
 +
<pre lang='xquery'>
 +
for $item in db:get('data')//item
 +
return $item update {
 +
  delete node ./text()
 +
}
 +
</pre>
 +
 
 +
If multiple nodes are supplied as input, the updates will subsequently be performed on each node:
 +
 
 +
<pre lang='xquery'>
 +
db:get('data')//item update {
 +
  delete node text()
 +
}
 +
</pre>
 +
 
 +
It is easy to chain subsequent update expressions:
 +
 
 +
<pre lang='xquery'>
 +
<root/> update {
 +
  insert node <child/> into .
 +
} update {
 +
  insert node "text" into child
 +
}
 +
</pre>
 +
 
 +
===transform with===
 +
 
 +
The {{Code|transform with}} expression was added to the current [https://www.w3.org/TR/xquery-update-30/#id-transform-with XQuery Update 3.0] working draft. It is a simplified version of the [[#update|update]] expression (it is limited to single input nodes and cannot be chained):
 +
 
 +
<pre lang='xquery'>
 +
<xml>text</xml> transform with {
 +
  replace value of node . with 'new-text'
 +
}
 +
</pre>
 +
 
 +
==Functions==
 +
 
 +
===Built-in Functions===
 +
 
 +
Numerous [[Database Module#Updates|Database Functions]] exist in BaseX for performing document- and database-wide updates.
 +
 
 +
XQUF provides a single function {{Code|fn:put()}} for serializing nodes to secondary storage:
 +
 
 +
* The function will be executed after all other updates.
 +
* Serialized documents therefore reflect all changes made effective during a query.
 +
* No files will be created if the addressed nodes have been deleted.
 +
* Serialization parameters can be specified as third argument (more details are found in the [https://www.w3.org/TR/xquery-update-30/#id-func-put XQUF 3.0 Specification]).
 +
 
 +
If you want to write intermediate results to files, it is more flexible to use {{Function|File|file:write}}.
 +
 
 +
===User-Defined Functions===
 +
 
 +
Functions that performs updates need to be marked with an {{Code|%updating}} annotation:
 +
 
 +
<pre lang='xquery'>
 +
declare %updating function local:add($target, $node) {
 +
  insert node $node into $target
 +
};
 +
 
 +
<node/> update {
 +
  local:add(., <sub/>)
 +
}
 +
</pre>
 +
 
 +
If update operations are defined in an anonymous function, it may be necessary to call the function with an additional {{Code|updating}} keyword:
 +
 
 +
<pre lang='xquery'>
 +
let $add := %updating function($target, $node) {
 +
  insert node $node into $target
 +
}
 +
return <node/> update {
 +
  updating $add(., <sub/>)
 +
}
 +
</pre>
 +
 
 +
=Concepts=
 +
 
 +
In addition to the '''simple expression''', XQUF introduced '''updating expressions''':
 +
 
 +
* All existing expressions are simple expressions. If such an expression is evaluated, the result is a sequence of items.
 +
* Updating expressions, which are presented in this article, result in a list of update primitives that are added to the '''Pending Update List'''.
 +
 
 +
==Pending Update List==
 +
 
 +
Updating statements are not executed immediately, but are first collected as update primitives within a set-like structure, the so-called Pending Update List (PUL). After the evaluation of the query, and after some consistency checks and optimizations, the update primitives will be applied in the following order:
 +
 
 +
* '''Backups, Binary resources''': {{Function|Database|db:alter-backup}}, {{Function|Database|db:create-backup}}, {{Function|Database|db:put-value}}, {{Function|Database|db:put-binary}}
 +
* '''XQuery Update''': {{Code|insert before}}, {{Code|delete}}, {{Code|replace}}, {{Code|rename}}, {{Code|replace value}}, {{Code|insert attribute}}, {{Code|insert into first}}, {{Code|insert into}}, {{Code|insert into last}}, {{Code|insert}}, {{Code|insert after}}, {{Code|fn:put}}
 +
* '''Documents''': {{Function|Database|db:add}}, {{Function|Database|db:put}}, {{Function|Database|db:rename}}, {{Function|Database|db:delete}}, {{Function|Database|db:optimize}}, {{Function|Database|db:flush}},
 +
* '''Users''': {{Function|User|user:grant}}, {{Function|User|user:password}}, {{Function|User|user:drop}}, {{Function|User|user:alter}}, {{Function|User|user:create}}
 +
* '''Databases''': {{Function|Database|db:copy}}, {{Function|Database|db:drop}}, {{Function|Database|db:alter}}, {{Function|Database|db:create}}
 +
* '''Backups''': {{Function|Database|db:restore}}, {{Function|Database|db:drop-backup}}
 +
 
 +
If an inconsistency is found, an error message is returned and all accessed databases remain untouched (ensuring atomicity). For the user, this means that updates are only visible '''after''' the end of a snapshot.
 +
 
 +
It may be surprising to see <code>[[Database Module|db:create]]</code> in the lower part of this list. This means that a newly created database cannot be accessed by the same query, which can be explained by the semantics of updating queries: all expressions can only be evaluated on databases that already exist while the query is evaluated. As a consequence, {{Code|db:create}} is mainly useful in the context of [[Commands#Basics|Command Scripts]], or [[Web Application]]s, in which a redirect to another page can be triggered after having created a database.
 +
 
 +
===Example===
 +
 
 +
The query…
 +
 
 +
<pre lang='xquery'>
 +
insert node <b/> into /doc,
 +
/doc/* ! (rename node . as 'renamed')
 +
</pre>
 +
 
 +
…applied on the document…
 +
 
 +
<pre lang="xml">
 +
<doc> <a/> </doc>
 +
</pre>
 +
 
 +
…results in the following document:
 +
 
 +
<pre lang="xml">
 +
<doc> <renamed/><b/> </doc>
 +
</pre>
 +
 
 +
Despite explicitly renaming all child nodes of {{Code|<doc/>}}, the former {{Code|<a/>}} element is the only one to be renamed. The {{Code|&lt;b/>}} element is inserted within the same snapshot and is therefore not yet visible to the user.
 +
 
 +
==Returning Results==
 +
 
 +
By default, it is not possible to mix different types of expressions in a query result. The root expression of a query must be a sequence of updating expressions. But there are two ways out:
 +
 
 +
* The BaseX-specific {{Function|Update|update:output}} function bridges this gap: it caches the results of its arguments at runtime and returns them after all updates have been processed. The following example performs an update and returns a success message:
 +
 
 +
<pre lang='xquery'>
 +
update:output("Update successful."), insert node <c/> into doc('factbook')/mondial
 +
</pre>
 +
 
 +
* With {{Option|MIXUPDATES}}, all updating constraints will be turned off. Returned nodes will be copied before they are modified by updating expressions. An error is raised if items are returned within a transform expression.
 +
 
 +
If you want to modify nodes in main memory, you can use the [[Update#transform|transform expression]].
 +
 
 +
==Effects==
 +
 
 +
==Original Files==
 +
 
 +
In BaseX, all updates are performed on database nodes or in main memory. By default, update operations do not affect the original input file (the info string "Updates are not written back" appears in the query info to indicate this). The following solutions exist to write XML documents and binary resources to disk:
 +
 
 +
* Updates on main-memory instances of files that have been retrieved via {{Code|fn:doc}} or {{Code|fn:collection}} will be propagated back to disk if {{Option|WRITEBACK}} is turned on. This option can also be activated on [[Command-Line Options#BaseX Standalone|command line]] via <code>-u</code>. Make sure you back up the original documents before running your queries.
 +
* Functions like {{Code|fn:put}} or {{Function|File|file:write}} can be used to write single XML documents to disk. With {{Function|File|file:write-binary}}, you can write binary resources.
 +
* The {{Command|EXPORT}} command can be used write all resources of a databases to disk.
  
 
==Indexes==
 
==Indexes==
As BaseX aims mainly for efficiency, the maintenance of indexes is left to the user.
 
This requires the user to call the [[Commands#Optimize|Optimize]]
 
command if up-to-date index structures are
 
necessary. Using this approach guarantees fast updates and fast access at the same time.
 
  
==Fragments==
+
Index structures are discarded after update operations when {{Option|UPDINDEX}} is turned off (which is the default).
So far BaseX differentiates between fragments and database nodes. Updates on fragments
+
More details are found in the article on [[Index#Updates|Indexing]].
have no effect on any existing databases and are therefore not applied at all. This
+
 
includes the test for violation of any constraints. Thus it is possible to execute an
+
=Error Messages=
update on a fragment, which would raise an error if applied on a database node.
+
 
 +
Along with the Update Facility, a number of new error codes and messages have been added to the specification and BaseX. All errors are listed in the [[XQuery Errors#Update Errors|XQuery Errors]] overview.
 +
 
 +
Please remember that the collected updates will be executed after the query evaluation. All logical errors will be raised before the updates are actually executed.
 +
 
 +
=Changelog=
  
;Example 1:
+
;Version 10.0
: Query: <pre>insert node attribute id{'1'} into &lt;a id='0'/></pre>
+
* Updated: {{Function|Database|db:put-binary}} is executed before XQuery Update expressions.
: Result:
+
* Updated: [[#update|update]]: Curly braces are now mandatory.
  
;Example 2:
+
;Version 9.0
: Query: <pre>insert node attribute id{'0'} into doc('doc.xml')//n</pre>
+
* Updated: [[#Built-in Functions|Built-in Functions]]: serialization parameters
: File 'doc.xml': <code>&lt;n id='1'/&gt;</code>
 
: Result: <code>[XUDY0021] Duplicate attribute "id".</code>
 
  
===Fragments & fn:put()===
+
;Version 8.5
As a consequence, updates on a fragment are not visible in an XML file created with
+
* Added: [[#transform with|transform with]]
<code>fn:put()</code>. If this functionality is required, the transform expression can be applied.
+
* Updated: [[#update|update]] was extended.
The copied  nodes in a transform expression are internally treated like database nodes
 
and are updatable as a result.
 
  
;Example 1:
+
;Version 8.0
: Query:
+
* Added: <code>MIXUPDATES</code> option for [[#Returning Results|Returning Results]] in updating expressions
: <pre>let $n := &lt;n/&gt; &#10; return (insert node &lt;x/&gt; into $n, put($n,'doc.xml'))</pre>
+
* Added: information message if files are not written back
: Resulting File 'doc.xml': <code>&lt;n/&gt;</code>
 
  
;Example 2:
+
;Version 7.8
: Query: <pre>put( &#10; copy $nn := &lt;n/&gt; &#10; modify insert node &lt;x/&gt; into $nn &#10; return $nn, 'doc.xml' &#10; )</pre>
+
* Added: [[#update|update]] convenience operator
: Resulting File 'doc.xml': <code> &lt;n&gt; &lt;x/&gt; &lt;/n&gt;</code>
 
[[Category:XQuery]]
 
[[Category:Finish]]
 

Latest revision as of 23:00, 25 March 2024

This article is part of the XQuery Portal. It summarizes the update features of BaseX.

BaseX offers a complete implementation of the XQuery Update Facility (XQUF). This article aims to provide a quick and basic introduction to XQUF. First, some examples for update expressions are given. Next, the challenges are addressed that arise due to the functional semantics of the language.

Features[edit]

Updating Expressions[edit]

There are five new expressions to modify data. While insert, delete, rename and replace are basically self-explanatory, the transform expression is different, as modified nodes are copied in advance and the original databases remain untouched.

An expression consists of one or more target nodes (the nodes we want to alter) and (depending on the expression type) additional information like nodes to be inserted, a QName, etc., and optional modifiers. You can find a few examples and additional information below.

insert[edit]

insert node (attribute { 'a' } { 5 }, 'text', <e/>) into /n

Insert enables you to insert a sequence of nodes into a single target node. Several modifiers are available to specify the exact insert location: insert into as first/as last, insert before/after and insert into.

Note: in most cases, as last and after are evaluated faster than as first and before.

delete[edit]

delete node //n

The example query deletes all <n> elements in your database. In contrast to other updating expressions, multiple nodes can be supplied as a target.

replace[edit]

replace node /n with <a/>

The target element is replaced by the DOM node <a/>. You can also replace the value of a node and its descendants by using the modifier value of:

replace value of node /n with 'newValue'

All descendants of /n are deleted, and the supplied text is inserted as the only child. The result of the insert sequence is either a single text node or an empty sequence. If the insert sequence is empty, all descendants of the target are deleted. Consequently, replacing the value of a node leaves the target with either a single text node or no descendants at all.

rename[edit]

for $n in //originalNode
return rename node $n as 'renamedNode' 

All originalNode elements are renamed. A loop can be used to modify multiple nodes within a single statement. Nodes on the descendant or attribute axis of the target are not affected.

Main-Memory Updates[edit]

With the following expressions, copies of nodes are created, which can then be modified with the already presented updating expressions. As the original node will not be changed, the expressions are called non-updating.

copy/modify/return[edit]

copy $c := doc('example.xml')//originalNode
modify rename node $c as 'copyOfNode'
return $c

A copy of the originalNode element is created, renamed and returned; the original document will not be updated.

In the following example, multiple update operations are performed on the copied node:

Query
copy $c :=
  <entry>
    <title>Transform expression example</title>
    <author>BaseX Team</author>
  </entry>
modify (
  replace value of node $c/author with 'BaseX',
  replace value of node $c/title with concat('Copy of: ', $c/title),
  insert node <author>Joey</author> into $c
)
return $c
Result
<entry>
  <title>Copy of: Transform expression example</title>
  <author>BaseX</author>
  <author>Joey</author>
</entry>

Instead of the main-memory <entry> element, a database node can be supplied:

copy $c := (db:get('example')//entry)[1]
...

In this case, the database node remains untouched, as all updates are performed on the node copy.

Entire documents can be copied and modified:

copy $doc := doc("zaokeng.kml")
modify (
  for $point in $doc//*:Point
  return insert node (
    <extrude>1</extrude>,
    <altitudeMode>relativeToGround</altitudeMode>
  )  before $point/*:coordinates
)
return $doc

update[edit]

The update expression is a BaseX-specific convenience operator for the bulky copy/modify/return construct. Similar to the XQuery 3.0 map operator, the nodes resulting from the first expression are bound as context items, and the bracketed expressions performs updates on the item. The updated nodes is returned as result:

for $item in db:get('data')//item
return $item update {
  delete node ./text()
}

If multiple nodes are supplied as input, the updates will subsequently be performed on each node:

db:get('data')//item update {
  delete node text()
}

It is easy to chain subsequent update expressions:

<root/> update {
  insert node <child/> into .
} update {
  insert node "text" into child
}

transform with[edit]

The transform with expression was added to the current XQuery Update 3.0 working draft. It is a simplified version of the update expression (it is limited to single input nodes and cannot be chained):

<xml>text</xml> transform with {
  replace value of node . with 'new-text'
}

Functions[edit]

Built-in Functions[edit]

Numerous Database Functions exist in BaseX for performing document- and database-wide updates.

XQUF provides a single function fn:put() for serializing nodes to secondary storage:

  • The function will be executed after all other updates.
  • Serialized documents therefore reflect all changes made effective during a query.
  • No files will be created if the addressed nodes have been deleted.
  • Serialization parameters can be specified as third argument (more details are found in the XQUF 3.0 Specification).

If you want to write intermediate results to files, it is more flexible to use file:write.

User-Defined Functions[edit]

Functions that performs updates need to be marked with an %updating annotation:

declare %updating function local:add($target, $node) {
  insert node $node into $target
};

<node/> update {
  local:add(., <sub/>)
}

If update operations are defined in an anonymous function, it may be necessary to call the function with an additional updating keyword:

let $add := %updating function($target, $node) {
  insert node $node into $target
}
return <node/> update {
  updating $add(., <sub/>)
}

Concepts[edit]

In addition to the simple expression, XQUF introduced updating expressions:

  • All existing expressions are simple expressions. If such an expression is evaluated, the result is a sequence of items.
  • Updating expressions, which are presented in this article, result in a list of update primitives that are added to the Pending Update List.

Pending Update List[edit]

Updating statements are not executed immediately, but are first collected as update primitives within a set-like structure, the so-called Pending Update List (PUL). After the evaluation of the query, and after some consistency checks and optimizations, the update primitives will be applied in the following order:

If an inconsistency is found, an error message is returned and all accessed databases remain untouched (ensuring atomicity). For the user, this means that updates are only visible after the end of a snapshot.

It may be surprising to see db:create in the lower part of this list. This means that a newly created database cannot be accessed by the same query, which can be explained by the semantics of updating queries: all expressions can only be evaluated on databases that already exist while the query is evaluated. As a consequence, db:create is mainly useful in the context of Command Scripts, or Web Applications, in which a redirect to another page can be triggered after having created a database.

Example[edit]

The query…

insert node <b/> into /doc,
/doc/* ! (rename node . as 'renamed')

…applied on the document…

<doc> <a/> </doc>

…results in the following document:

<doc> <renamed/><b/> </doc>

Despite explicitly renaming all child nodes of <doc/>, the former <a/> element is the only one to be renamed. The <b/> element is inserted within the same snapshot and is therefore not yet visible to the user.

Returning Results[edit]

By default, it is not possible to mix different types of expressions in a query result. The root expression of a query must be a sequence of updating expressions. But there are two ways out:

  • The BaseX-specific update:output function bridges this gap: it caches the results of its arguments at runtime and returns them after all updates have been processed. The following example performs an update and returns a success message:
update:output("Update successful."), insert node <c/> into doc('factbook')/mondial
  • With MIXUPDATES, all updating constraints will be turned off. Returned nodes will be copied before they are modified by updating expressions. An error is raised if items are returned within a transform expression.

If you want to modify nodes in main memory, you can use the transform expression.

Effects[edit]

Original Files[edit]

In BaseX, all updates are performed on database nodes or in main memory. By default, update operations do not affect the original input file (the info string "Updates are not written back" appears in the query info to indicate this). The following solutions exist to write XML documents and binary resources to disk:

  • Updates on main-memory instances of files that have been retrieved via fn:doc or fn:collection will be propagated back to disk if WRITEBACK is turned on. This option can also be activated on command line via -u. Make sure you back up the original documents before running your queries.
  • Functions like fn:put or file:write can be used to write single XML documents to disk. With file:write-binary, you can write binary resources.
  • The EXPORT command can be used write all resources of a databases to disk.

Indexes[edit]

Index structures are discarded after update operations when UPDINDEX is turned off (which is the default). More details are found in the article on Indexing.

Error Messages[edit]

Along with the Update Facility, a number of new error codes and messages have been added to the specification and BaseX. All errors are listed in the XQuery Errors overview.

Please remember that the collected updates will be executed after the query evaluation. All logical errors will be raised before the updates are actually executed.

Changelog[edit]

Version 10.0
  • Updated: db:put-binary is executed before XQuery Update expressions.
  • Updated: update: Curly braces are now mandatory.
Version 9.0
Version 8.5
Version 8.0
  • Added: MIXUPDATES option for Returning Results in updating expressions
  • Added: information message if files are not written back
Version 7.8
  • Added: update convenience operator