我想复制一份文档并修改其中的一个节点,最好是在一个事务中。似乎最好的方法是克隆旧文档,使用 in-mem-update 库对其进行修改,然后将其写入新的 URI。但我到目前为止只是写了原始文档,没有任何修改。
doc1.xml
:
<root>
<foo>bar</foo>
</root>
到目前为止我所拥有的:
declareUpdate();
const mem = require("/custom-modules/utils/in-mem-update.xqy");
let oldUri = "/test/doc1.xml";
let newUri = "/test/doc2.xml";
let oldDoc = cts.doc(oldUri);
let newDoc = fn.head(xdmp.unquote(JSON.parse(JSON.stringify(oldDoc))));
let nb = new NodeBuilder();
nb.startElement("foo");
nb.addText("baz");
nb.endElement();
mem.nodeReplace(fn.head(newDoc.xpath("/root/foo")), nb.toNode());
xdmp.documentInsert(newUri, newDoc);
有更好的方法吗?
最佳答案
我同意 Mads 的观点,内存更新库往往很慢。它会根据您应用的每个更改构建一个新的节点树。有一个较新的副本可以一次性完成所有更改,从而提高效率。这可能是 Mads 描述的 XSLT 方法的一个很好的替代方案:
https://github.com/ryanjdew/XQuery-XML-Memory-Operations
也就是说,你已经很接近了。您错过了这样一个事实:mem 函数返回节点树的更改副本,而不是像 xdmp 节点函数那样就地更改它。只需在 mem.nodeReplace
调用前面添加 newDoc =
即可使代码正常工作:
declareUpdate();
const mem = require('/MarkLogic/appservices/utils/in-mem-update.xqy');
let oldUri = "/test/doc1.xml";
let newUri = "/test/doc2.xml";
let oldDoc = cts.doc(oldUri);
let newDoc = fn.head(xdmp.unquote(JSON.parse(JSON.stringify(oldDoc))));
let nb = new NodeBuilder();
nb.startElement("foo");
nb.addText("baz");
nb.endElement();
newDoc = mem.nodeReplace(fn.head(newDoc.xpath("/root/foo")), nb.toNode());
//xdmp.documentInsert(newUri, newDoc);
newDoc
呵呵!
关于javascript - 如何在 MarkLogic Javascript 中复制和修改文档?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65633533/