XQuery Update:根据节点是否存在而插入或替换?

时间:2011-03-17 05:01:05

标签: xquery exist-db basex xquery-update

我正在尝试构建简单的XML数据库(在BaseX或eXist-db中),但我无法确定如何修改文档中的值:

内容很简单,因为测试:

<p>
    <pl>
        <id>6></id>
    </pl>
</p>

我正在尝试构建类似函数的东西,如果该元素不存在则将元素插入<pl>或者如果存在则替换它。但XQuery给了我麻烦:

当我用if-then-else逻辑正面试试时:

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'

我收到错误Error: [XUDY0027] Replace target must not be empty。显然我很困惑,为什么在两种情况下评估else部分,因此错误。 当我清空其他部分时:

if (exists(/p/pl[id=6]/name)=true)
    then insert node <name>thenname</name> into /p/pl[id=6]
    else <dummy/>

然后我得到Error: [XUST0001] If expression: no updating expression allowed

当我尝试声明更新功能时,即使它报告错误:

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.

我从BaseX 6.5.1包中收到了这些错误。

那么如果可能的话,如何以简单的方式修改值呢? 如果我直接调用 insert ,则可能存在多个具有相同值的元素。 如果我调用 replace ,当节点不存在时,它将失败。 如果我在插入/替换之前删除节点,那么我可以销毁我不想要的子节点。

在大多数SQL数据库中,这些都是非常简单的任务(如MYSQL' replace '命令)。

1 个答案:

答案 0 :(得分:5)

@Qiqi:@Alejandro是对的。您的if表达式不正确 XQuery语法:

if (exists(/p/pl[id=6]/name))
then insert node <name>thenname</name> into /p/pl[id=6]
else replace value of node /p/pl[id=6]/name with 'elsename'

请注意,eXist-db的XQuery Update功能目前是特定于eXist的实现,因此在eXist(当前)1.4.x和1.5dev中,您需要:

if (exists(/p/pl[id=6]/name))
then update insert <name>thenname</name> into /p/pl[id=6]
else update value /p/pl[id=6]/name with 'elsename'

这个特定于eXist的XQuery Update语法记录在http://exist-db.org/update_ext.html上。此语法是在W3C XQuery Update规范达到其当前状态之前开发的。 eXist团队计划尽快使eXist完全符合W3C规范,但与此同时,如果您使用eXist,上述文档应该可以帮助您实现所需的目标。

另请注意,您的示例代码在pl和id元素中包含拼写错误。有效的XML版本是:

<p>
  <pl>
    <id>6</id>
  </pl>
</p>