XQuery Update: insert or replace depending if node exists not possible ?
Thursday, 17 March 2011 · 3 messages
PV
Petr Vacek17 Mar 2011 06:46 #
Greetings, I am trying to build simple XML database (inside baseX or existdb
- but baseX seems nicer for java APIs), but I have trouble figuring how to modify values in document :
content is simple as this for test :
<p>
</pl>
<id>6></id>
</pl>
</p>I am trying to build something like function which would insert element into <pl> if that element is not present or replace it if it is present. But Xquery is giving me troubles yet :
When I try it head-on with if-then-else logic :
if (exists(/p/pl[id=6]/name)=false)
then insert node <name>thenname</name> into /p/pl[id=6]
else replace value of node /p/pl[id=6]/name with 'elsename'I get error Error: [XUDY0027] Replace target must not be empty. - clearly I am confused, why the else part is evaluated in both cases, thus the error. When I empty out the else part :
if (exists(/p/pl[id=6]/name)=true)
then insert node <name>thenname</name> into /p/pl[id=6]
else <dummy/>
Then I get Error: [XUST0001] If expression: no updating expression allowed.
When I try through declaring updating function, even then it reports error : declare namespace testa='test';
declare updating function testa:bid($a, $b)
{
if (exists(/p/pl[id=6]/name)=true)
then insert node <name>thenname</name> into /p/pl[id=6]
else <dummy/>
};
testa:bid(0,0)Error: [XUST0001] If expression: no updating expression allowed.
I've got these errors from baseX 6.5.1 package.
So how can I modify values in a simple fashion if possible ? If I call insert straight, the there could be multiple elements of same value. If I call replace it will fail when the node does not exist. If I delete the node before insert/replace then I could destroy sub-nodes which I don't want.
In most SQL databases, these are quite simple task (like MYSQL 'replace' command).
Thanks in advance for any hints and tips how to get basic 'replace' functionality done.
Regards
Petr Vacek
HV
Huib Verweij17 Mar 2011 07:51 #
Hi Petr,
Op 17 mrt 2011, om 06:46 heeft Petr Vacek het volgende geschreven:
Quoted text · Petr Vacek · 17 lines
> When I try through declaring updating function, even then it reports error : > declare namespace testa='test'; > > declare updating function testa:bid($a, $b) > { > if (exists(/p/pl[id=6]/name)=true) > then insert node <name>thenname</name> into /p/pl[id=6] > else <dummy/> > }; > > testa:bid(0,0) > > Error: [XUST0001] If expression: no updating expression allowed. > > I've got these errors from baseX 6.5.1 package. > > So how can I modify values in a simple fashion if possible ? If I call insert straight, the there could be multiple elements of same value. If I call replace it will fail when the node does not exist. If I delete the node before insert/replace then I could destroy sub-nodes which I don't want.
You definitely need to "declare updating function()", however, an updating function can never return a value (just like SQL UPDATE doesn't return a value from the database query). The sneaky part in XQuery Update is that the 'updating quality' bubbles up, e.g. when function A() calls an updating function B(), function A() is also an updating function (at least that's my understanding). Therefore, you're entire xquery is an updating function, so the whole thing can't return a value, not even <dummy/>. You can use the empty sequence () as a return value though.
Hartelijke groet,
Huib.
--
Drs. Huib Verweij
Senior software developer - The Language Archive
Max Planck Institute for Psycholinguistics
P.O. Box 310
6500 AH Nijmegen
The Netherlands
t +31-24-3521911
e huib.verwey at mpi.nl
w http://www.mpi.nl/
AW
Andreas Weiler17 Mar 2011 13:08 #
Hi Petr,
a working example would be:
Query:
declare namespace testa='test';
declare updating function testa:bid($a, $b)
{
if (exists(/p[id=6]))
then insert node <name>thenname</name> into /p[id=6]
else ()
};
testa:bid(0,0)DB: create db test "<p><pl/><id>6</id><pl/></p>"
-- Andreas
Quoted text · Huib Verweij · 45 lines
Am 17.03.2011 um 07:51 schrieb Huib Verweij: > Hi Petr, > > Op 17 mrt 2011, om 06:46 heeft Petr Vacek het volgende geschreven: > >> When I try through declaring updating function, even then it reports error : >> declare namespace testa='test'; >> >> declare updating function testa:bid($a, $b) >> { >> if (exists(/p/pl[id=6]/name)=true) >> then insert node <name>thenname</name> into /p/pl[id=6] >> else <dummy/> >> }; >> >> testa:bid(0,0) >> >> Error: [XUST0001] If expression: no updating expression allowed. >> >> I've got these errors from baseX 6.5.1 package. >> >> So how can I modify values in a simple fashion if possible ? If I call insert straight, the there could be multiple elements of same value. If I call replace it will fail when the node does not exist. If I delete the node before insert/replace then I could destroy sub-nodes which I don't want. > > You definitely need to "declare updating function()", however, an updating function can never return a value (just like SQL UPDATE doesn't return a value from the database query). The sneaky part in XQuery Update is that the 'updating quality' bubbles up, e.g. when function A() calls an updating function B(), function A() is also an updating function (at least that's my understanding). Therefore, you're entire xquery is an updating function, so the whole thing can't return a value, not even <dummy/>. You can use the empty sequence () as a return value though. > > Hartelijke groet, > > Huib. > > > -- > Drs. Huib Verweij > Senior software developer - The Language Archive > Max Planck Institute for Psycholinguistics > P.O. Box 310 > 6500 AH Nijmegen > The Netherlands > t +31-24-3521911 > e huib.verwey at mpi.nl > w http://www.mpi.nl/ > > _______________________________________________ > BaseX-Talk mailing list > BaseX-Talk at mailman.uni-konstanz.de > https://mailman.uni-konstanz.de/mailman/listinfo/basex-talk
Written for BaseX 6. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery