|
|
|||
XML Updates
MonetDB/XQuery fully supports the W3C
XQuery Update Facility (XQUF),
except for the note:August 2007, W3C published a new and final call that makes some changes to the syntax (e.g. do insert became insert node). These changes are not supported yet in this version of MonetDB/XQuery.
Start the Mserver, open an interactive
> pf:add-doc("http://monetdb.cwi.nl/XQuery/files/HelloWorld.xml",
"greetings.xml", "greetings.xml", 10)
Only by passing a fourth parameter percentage between 1 and 99 (free-space to accommodate inserts - a performance tuning setting) we added the document as a updatable collection to our database.
Now let's perform some updates:
Insert As First/Last
> do insert <start/> as first into doc("greetings.xml")/doc
Update commands do not return any result. But we can now re-inspect the document:
> doc("greetings.xml")
<?xml version="1.0" encoding="utf-8"?>
<doc><start/>
<greet kind="informal">Hi </greet>
<greet kind="casual">Hello </greet>
<location kind="global">World</location>
<location kind="local">Amsterdam</location>
</doc>
We inserted a new element directly as first child after <doc>.
The absence of free space between <doc> and <code>
shows there is no other (text) node between them.
> do insert <end/> as last into doc("greetings.xml")/doc
Now we inserted a new element as a last child after <doc>:
> doc("greetings.xml")
<?xml version="1.0" encoding="utf-8"?>
<doc><start/>
<greet kind="informal">Hi </greet>
<greet kind="casual">Hello </greet>
<location kind="global">World</location>
<location kind="local">Amsterdam</location>
<end/></doc>
Delete NodesOne can delete multiple nodes in one XQUFdo delete command.
Except for deletion, all update commands of the XQUF work on a single target node.
> let $doc := doc("greetings.xml") return do delete ($doc//start, $doc//end)
Now the <start/> and <end/> are gone again.
Insert Before/AfterWe can also insert a new element before another element:
> do insert <greet kind="formal">Good day</greet>
before doc("greetings.xml")//greet[1]
Note that now there is no text node between the first two greetings:
> doc("greetings.xml")
<?xml version="1.0" encoding="utf-8"?>
<doc>
<greet kind="formal">Good day</greet><greet kind="informal">Hi </greet>
<greet kind="casual">Hello </greet>
<location kind="global">World</location>
<location kind="local">Amsterdam</location>
</doc>
This can be fixed with an extra insert after:
> do insert text {"
"} after doc("greetings.xml")//greet[1]
Alternatively, one could have inserted two nodes directly:
> do insert (<greet kind="formal">Good day</greet>, text {"
"}) before doc("greetings.xml")//greet[1]
In both cases, the result is:
> doc("greetings.xml")
<?xml version="1.0" encoding="utf-8"?>
<doc>
<greet kind="formal">Good day</greet>
<greet kind="informal">Hi </greet>
<greet kind="casual">Hello </greet>
<location kind="global">World</location>
<location kind="local">Amsterdam</location>
</doc>
Replace NodeAn entire node can be replaced by one or more new nodes:
> do replace doc("greetings.xml")//greet[1]
with <greet kind="polite">Pleased to meet you</greet>
resulting in:
> doc("greetings.xml")
<?xml version="1.0" encoding="utf-8"?>
<doc>
<greet kind="polite">Pleased to meet you</greet>
<greet kind="informal">Hi </greet>
<greet kind="casual">Hello </greet>
<location kind="global">World</location>
<location kind="local">Amsterdam</location>
</doc>
Replace ValueWe can also replace the value of attributes and (text) nodes:
> let $formal := doc("greetings.xml")//greet[1]
return
(do replace value of $formal/@kind with "impolite",
do replace value of $formal with "Bugger Off")
so now our first greeting is rather impolite:
> doc("greetings.xml")
<?xml version="1.0" encoding="utf-8"?>
<doc>
<greet kind="impolite">Bugger Off</greet>
<greet kind="informal">Hi </greet>
<greet kind="casual">Hello </greet>
<location kind="global">World</location>
<location kind="local">Amsterdam</location>
</doc>
Rename ElementAn element can also change name:
> do rename doc("greetings.xml")//greet[1] into "insult"
which turns our greeting into an insult:
> doc("greetings.xml")
<?xml version="1.0" encoding="utf-8"?>
<doc>
<insult kind="impolite">Bugger Off</insult>
<greet kind="informal">Hi </greet>
<greet kind="casual">Hello </greet>
<location kind="global">World</location>
<location kind="local">Amsterdam</location>
</doc>
NOTE: MonetDB/XQuery uses the syntax: do rename .. into ..instead of: do rename .. as .. due to problems in the XQUF Draft. Advanced UpdatesXQUF updating statements can be combined in complex statements, nested in for-loops, and even wrapped in updating functions:
> declare updating function foo($n as element(), $k as xs:integer)
{
if (count($n/@nr) = 0)
then do insert attribute nr { $k } into $n
else do replace value of $n/@nr with $k
};
for $greet at $k in doc("greetings.xml")//greet
return foo($greet, $k)
The above query takes all greetings, and adds a unique ascending
number attribute to them:
> doc("greetings.xml")
<?xml version="1.0" encoding="utf-8"?>
<doc>
<insult kind="impolite">Bugger Off</insult>
<greet kind="informal" nr="1">Hi </greet>
<greet kind="casual" nr="2">Hello </greet>
<location kind="global">World</location>
<location kind="local">Amsterdam</location>
</doc>
Note that adding new attributes to an XML element is done in the
XQUF using insert into, passing in an attribute node.
|
||||
| © 1994-2011 CWI | Contact us Legal HG web Bugs TestWeb | |||