XQuery 更新:插入或替换取决于节点是不是存在不可能?
Posted
技术标签:
【中文标题】XQuery 更新:插入或替换取决于节点是不是存在不可能?【英文标题】:XQuery Update: insert or replace depending if node exists not possible?XQuery 更新:插入或替换取决于节点是否存在不可能? 【发布时间】:2011-07-17 03:25:42 【问题描述】:我正在尝试构建简单的 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' 命令)。
【问题讨论】:
首先,奇怪的是XQuery 引擎没有抱怨那些使用上下文节点的表达式。其次,如果由于某种原因你想要xs:boolean
的真假实例,你应该使用true()
和false()
函数而不是child::true
缩写形式... 但我不认为你需要这个。只需使用 exists()
结果,它是一个布尔值。
按照@joewiz 的answerexistDB 重新标记不是XQuery 更新工具标准抱怨XQuery 引擎。
【参考方案1】:
@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 更新功能当前是特定于 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 更新语法记录在 http://exist-db.org/update_ext.html 上。此语法是在 W3C XQuery Update 规范达到其当前状态之前开发的。 eXist 团队计划尽快使 eXist 完全符合 W3C 规范,但与此同时,如果您使用 eXist,上述文档应该可以帮助您实现所需的目标。
还要注意,您的示例代码在 pl 和 id 元素中包含一个错字。有效的 XML 版本是:
<p>
<pl>
<id>6</id>
</pl>
</p>
【讨论】:
以上是关于XQuery 更新:插入或替换取决于节点是不是存在不可能?的主要内容,如果未能解决你的问题,请参考以下文章
sql:mysql:MySql 不存在则插入,存在则更新或忽略