Changes

Jump to navigation Jump to search
120 bytes removed ,  00:00, 26 March 2024
m
"b" tag was not being rendered, and escaping the left angle bracket seems to fix the problem
It summarizes the update features of BaseX.
BaseX offers a complete implementation of the [httphttps://www.w3.org/TR/xquery-update-10/ XQuery Update Facility (XQUF)]. This article aims to provide a very quick and basic introduction to the XQUF. First, some examples for update expressions are given. After thatNext, the challenges are addressed that arise due to the functional semantics of the language. These are stated in the [[Update#Concepts|Concepts]] paragraph.
=Features=
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.
An expression consists of a one or more target node nodes (the node nodes we want to alter) and (depending on the expression type) additional information like insertion nodesto be inserted, a QName, etc. which depends on the type of expression. Optional , and optional modifiers are available for some of them. You can find a few examples and additional information below.
===insert===
<pre classlang="brush:'xquery"'>
insert node (attribute { 'a' } { 5 }, 'text', <e/>) into /n
</pre>
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''' will be are evaluated faster than '''as first''' and '''before'''!.
===delete===
<pre classlang="brush:'xquery"'>
delete node //n
</pre>
The example query deletes all <code><n></code> elements in your database. Note that, in In contrast to other updating expressions, the delete expression allows multiple nodes can be supplied as a target.
===replace===
<pre classlang="brush:'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 or and its descendants by using the modifier '''value of'''.:
<pre classlang="brush:'xquery"'>
replace value of node /n with 'newValue'
</pre>
All descendants of /n are deleted , and the given supplied text is inserted as the only child. Note that the 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 classlang="brush:'xquery"'>
for $n in //originalNode
return rename node $n as 'renamedNode'
</pre>
All <code>originalNode</code> elements are renamed. An iterative approach helps 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. This has to be done explicitly as well.
==NonMain-Updating ExpressionsMemory 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 classlang="brush:'xquery"'>copy $c := doc('example.xml')//originalNode[@id = 1]
modify rename node $c as 'copyOfNode'
return $c
</pre>
The <code>A copy of the {{Code|originalNode</code> }} element with <code>@id=1</code> is copied created, renamed and subsequently assigned a new QName using returned; the rename expression. Note that the transform expression is the only expression which returns an actual XDM instance as a result. You can therefore use it to modify results and especially DOM nodes. This is an issue beginners are often confronted with. More on this topic can original document will not be found in the [[Update#Returning Results|XQUF Concepts]] sectionupdated.
The In the following example demonstrates a common use case, multiple update operations are performed on the copied node:
;Query:
<pre classlang="brush:'xquery"'>
copy $c :=
<entry>
</pre>
;Result:
<pre classlang="brush:xml">
<entry>
<title>Copy of: Transform expression example</title>
</pre>
The <code>Instead of the main-memory {{Code|<entry></code> }} element (here it is passed to the expression as , a DOM database node) can also be replaced by a database node, e.g.supplied:
<pre classlang="brush:'xquery"'>copy $c := (db:openget('example')//entry)[1]
...
</pre>
In this case, the original database node remains untouched as well, as all updates are performed on the node copy.
Here is an example where we return an entire document, parts Entire documents can be copied and modifiedand all:
<pre classlang="brush:'xquery"'>copy $c doc := doc("zaokeng.kml")
modify (
for $d point in $cdoc//*:Point
return insert node (
<extrude>1</extrude>,
<altitudeMode>relativeToGround</altitudeMode>
) before $dpoint/*:coordinates
)
return $cdoc
</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:
* Similar to the [[XQuery 3.0#Simple Map Operator|XQuery 3.0 map operator]], the value of the firstexpression is bound as context item, and the second expression performs updates on this item.The updated item is returned as result: <pre classlang="brush:'xquery"'>for $item in db:openget('data')//itemreturn $item update { delete node ./text()}
</pre>
* More than one If multiple nodes are supplied as input, the updates will subsequently be performed on each node can be specified as source:
<pre classlang="brush:'xquery"'>db:openget('data')//item update { delete node text()}
</pre>
* If wrapped with curly braces, It is easy to chain subsequent update expressions can be chained:
<pre classlang="brush:'xquery"'>
<root/> update {
insert node <child/> into .
===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 simple simplified version of the [[#update|update]] expression (it is limited to single input nodes and also available in BaseXcannot be chained):
<pre classlang="brush:'xquery"'>
<xml>text</xml> transform with {
replace value of node . with 'new-text'
===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()}} is can be used to serialize XDM instances for serializing nodes to secondary storage:
* The function will be executed after all other updates.
* 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]).
Numerous additional [[Database Module#UpdatesIf you want to write intermediate results to files, it is more flexible to use {{Function|database functions]] exist for performing updates on document and database levelFile|file:write}}.
===User-Defined Functions===
If an updating function item is called, the function call must Functions that performs updates need to be prefixed marked with the keyword an {{Code|%updating}}. This ensures that the query compiler can statically detect if an invoked annotation: <pre lang='xquery'>declare %updating function item will perform updates or notlocal:add($target, $node) { insert node $node into $target};
<pre class="brush:xquery">let $node := <node>TO-BE-DELETED</node>update {let $delete-text local:= %updating functionadd($node) { delete node $node., <sub//text(>)
}
return $node update (
updating $delete-text(.)
)
</pre>
As shown If update operations are defined in the examplean anonymous function, user-defined and anonymous functions can additionally it may be annotated as necessary to call the function with an additional {{Code|updating}} keyword: <pre lang='xquery'>let $add := %updatingfunction($target, $node) { insert node $node into $target}return <node/> update { updating $add(., <sub/>)}.</pre>
=Concepts=
There are a few specialties around XQuery Update that you should know about. In addition to the '''simple expression''', the XQUF adds the introduced '''updating expressionexpressions''' as : * All existing expressions are simple expressions. If such an expression is evaluated, the result is a new type sequence of expressionitems. An updating expression returns only * Updating expressions, which are presented in this article, result in a list of update primitives that are added to the '''Pending Update List (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==
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 so-called Pending Update List (PUL). At After the end evaluation of a the query, and after some consistency checks and optimizations, the update primitives will be applied in the following order:
* '''Backups (1), Binary resources''': {{CodeFunction|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''': {{CodeFunction|Database|db:add()}}, {{CodeFunction|Database|db:store()put}}, {{CodeFunction|db:replace()}}, {{CodeDatabase|db:rename()}}, {{CodeFunction|Database|db:delete()}}, {{CodeFunction|Database|db:optimize()}}, {{CodeFunction|Database|db:flush()}},* '''Users''': {{CodeFunction|User|user:grant()}}, {{CodeFunction|User|user:password()}}, {{CodeFunction|User|user:drop()}}, {{CodeFunction|User|user:alter()}}, {{CodeFunction|User|user:create()}}* '''Databases''': {{CodeFunction|Database|db:copy()}}, {{CodeFunction|Database|db:drop()}}, {{CodeFunction|Database|db:alter()}}, {{CodeFunction|Database|db:create()}}* '''Backups (2)''': {{CodeFunction|Database|db:restore()}}, {{CodeFunction|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 classlang="brush:'xquery"'>
insert node <b/> into /doc,
for $n in /doc/child::node* ! ()return rename node $n . as 'justRenamedrenamed')
</pre>
…applied on the document…
<pre classlang="brush:xml">
<doc> <a/> </doc>
</pre>
…results in the following document:
<pre classlang="brush:xml"><doc> <justRenamedrenamed/><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 outermost root expression of a query must either be a collection sequence of updating or non-updating expressions. But there are two ways out:
* The BaseX-specific <code>[[{{Function|Update Module#update:output|update:output()]]</code> }} 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 classlang="brush:'xquery"'>
update:output("Update successful."), insert node <c/> into doc('factbook')/mondial
</pre>
* With the [[Options#MIXUPDATES{{Option|MIXUPDATES]] option}}, 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]].
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 when the <code>[[Options#WRITEBACKif {{Option|WRITEBACK]]</code> option }} 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{{Code|fn:put]]</code> }} or <code>[[{{Function|File Module#file:write|file:write]]</code> }} can be used to write single XML documents to disk. With <code>[[{{Function|File Module#file:write-binary|file:write-binary]]</code>}}, you can write binary resources.* The [[Commands#EXPORT{{Command|EXPORT]] }} command can be used write all resources of a databases to disk.
==Indexes==
Index structures are discarded after update operations when [[Options#UPDINDEX{{Option|UPDINDEX]] }} is turned off (which is the default).
More details are found in the article on [[Index#Updates|Indexing]].
=Error Messages=
Along with the Update Facility, a number of new error codes and messages have been addedto 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.If All logical errors occur at this final stage, they cannot will be caught via try/catchraised before the updates are actually executed.
=Changelog=
 
;Version 10.0
* Updated: {{Function|Database|db:put-binary}} is executed before XQuery Update expressions.
* Updated: [[#update|update]]: Curly braces are now mandatory.
;Version 9.0
administrator, editor
43

edits

Navigation menu