MarkLogic内存更新问题:无法删除文档中file-text元素
问题排查与解决方案
你的两段代码都没能成功删除file-text元素,核心问题出在对xdmp:document-insert返回值的误解,以及内存更新后的文档未正确处理上,下面逐个分析并给出修正方案:
第一段代码的问题
xdmp:document-insert("/abc.xml", doc("/xyz.xml"))的返回值并不是你插入的文档节点,而是一个记录插入操作状态的<xdmp:insert>元素(包含目标URI等元数据)。你把这个结果赋值给$createArchDoc后,$createArchDoc/document/file-text根本找不到对应的节点,自然无法执行删除操作。
修正后的代码应该先获取源文档的内存副本,完成删除后再插入到数据库:
xquery version "1.0-ml"; declare namespace html = "http://www.w3.org/1999/xhtml"; import module namespace mem = "http://xqdev.com/in-mem-update" at "/MarkLogic/appservices/utils/in-mem-update.xqy"; let $sourceDoc := doc("/xyz.xml") // 先对内存副本执行删除操作 let $updatedDoc := mem:node-delete($sourceDoc//file-text) // 将修改后的文档插入到目标URI return xdmp:document-insert("/abc.xml", $updatedDoc)
第二段代码的问题
这段代码的两个关键问题:
- 你只是对读取到的文档做了内存删除,但没有将修改后的内存文档写回数据库,所以数据库里的
/abc.xml还是原始内容; - 路径
$myNewDoc/document/file-text可能不符合你的文档结构——如果file-text是直接在文档根节点下,或者需要深层查找,应该用$myNewDoc//file-text或$myNewDoc/file-text(取决于实际文档结构)。
如果你的需求是修改数据库中的/abc.xml,修正后的代码如下:
xquery version "1.0-ml"; import module namespace mem = "http://xqdev.com/in-mem-update" at "/MarkLogic/appservices/utils/in-mem-update.xqy"; let $_ := xdmp:document-insert("/abc.xml", doc("/xyz.xml")) let $myNewDoc := doc("/abc.xml") // 正确定位file-text元素 let $updatedMemDoc := mem:node-delete($myNewDoc//file-text) // 将修改后的内存文档写回数据库覆盖原文档 return xdmp:document-insert("/abc.xml", $updatedMemDoc)
如果只是想得到删除后的内存文档(不需要持久化),调整路径后即可返回正确结果:
xquery version "1.0-ml"; import module namespace mem = "http://xqdev.com/in-mem-update" at "/MarkLogic/appservices/utils/in-mem-update.xqy"; let $_ := xdmp:document-insert("/abc.xml", doc("/xyz.xml")) let $myNewDoc := doc("/abc.xml") let $updatedMemDoc := mem:node-delete($myNewDoc//file-text) return $updatedMemDoc
额外提醒:mem:node-delete只会返回修改后的节点树,不会改变原内存节点或数据库中的文档,所以必须使用它的返回值来完成后续的持久化或输出操作。
内容的提问来源于stack exchange,提问作者Sukesh
相关产品推荐
相关产品推荐

