Marklogic - 如何在单个 xquery 中执行插入和节点替换

Marklogic - how to execute insert and node replace in single xquery

我提供了用于插入和节点替换查询的示例 Xquery。

我的问题是如果我要执行查询,它只会先插入 XML。

即使我要执行第二次,节点也会被替换。

但我希望单次执行也能处理插入和更新。

sample query :

xquery version "1.0-ml";
declare namespace html = "http://www.w3.org/1999/xhtml";
 let $a := xdmp:document-insert("/fo.xml", <a>1</a>)

let $b := xdmp:node-replace(fn:doc("/fo.xml")/a, <b>1</b>)

return ($a,$b)  

你不能在一条语句中做到这一点。您要么需要:

  1. 使用多语句调用(主语句用分号分隔)
  2. 在内存中进行更新,并将更新的内容传递给插入

关于 1:

应用程序开发人员指南中有一节关于 Semi-Colon as a Statement Separator,但简而言之,它归结为按如下方式编写您的查询:

xquery version "1.0-ml";
xdmp:document-insert("/fo.xml", <a>1</a>)
;
xquery version "1.0-ml";
xdmp:node-replace(fn:doc("/fo.xml")/a, <b>1</b>)

关于 2:

有些库提供的方法与 xdmp:node-* 方法非常相似,但对尚未持久保存到数据库的内容进行操作。您需要先下载它们,然后将它们上传到您的模块数据库才能使用它们。我知道的最好的版本是 https://github.com/ryanjdew/XQuery-XML-Memory-Operations. You can download and install that using MLPM。使用该库,您可以编写如下内容:

import module namespace mem = "http://maxdewpoint.blogspot.com/memory-operations" at "/ext/mlpm_modules/XQuery-XML-Memory-Operations/memory-operations.xqy";

let $a := <a>1</a>
let $b := <b>1</b>
let $updated-a := mem:copy($a) ! (
  mem:replace(., $a, $b),
  mem:execute(.)
)
return xdmp:document-insert("/foo.xml", $updated-a)

HTH!

根据 grtjn 的回答,您可以执行以下操作:

xdmp:document-insert("/fo.xml", <a>1</a>);
xdmp:node-replace(fn:doc("/fo.xml")/a, <b>1</b>);

注意行尾的分号。这些是语句分隔符。要了解有关语句分隔符(以及一般事务)的更多信息,您可以参考以下资源:https://docs.marklogic.com/guide/app-dev/transactions#id_11899.