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:
应用程序开发人员指南中有一节关于 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.
我提供了用于插入和节点替换查询的示例 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:
应用程序开发人员指南中有一节关于 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.