如何在MarkLogic Javascript中复制和修改文档?
我想复制一个文档并修改其中的一个节点,最好是在一个事务中。最好的方法似乎是克隆旧文档,使用内存更新库对其进行修改,然后将其写入新的URI。但到目前为止,我只写了原始文档,没有任何修改如何在MarkLogic Javascript中复制和修改文档?,javascript,marklogic,Javascript,Marklogic,我想复制一个文档并修改其中的一个节点,最好是在一个事务中。最好的方法似乎是克隆旧文档,使用内存更新库对其进行修改,然后将其写入新的URI。但到目前为止,我只写了原始文档,没有任何修改 doc1.xml: <root> <foo>bar</foo> </root> 有没有更好的方法可以做到这一点?内存中的更新库可能速度慢且效率低,尤其是在有大量更改且输入文档很大的情况下 通过XSLT和身份转换以及foo/text() 您还可以考虑在数据库中保存
doc1.xml
:
<root>
<foo>bar</foo>
</root>
有没有更好的方法可以做到这一点?内存中的更新库可能速度慢且效率低,尤其是在有大量更改且输入文档很大的情况下 通过XSLT和身份转换以及
foo/text()
您还可以考虑在数据库中保存XSLT,并使用<代码> xdMP.xsLTujk> < />代码>,而不是从JavaScript中解压缩序列化的XSLT字符串。只需将其全部内联以便于演示。
我同意Mads的观点,即内存中的更新库往往很慢。它使用您应用的每个更改构建一个新的节点树。有一个更新的副本,一次完成所有更改,使其更加高效。这可能是Mads描述的XSLT方法的一个很好的替代方法:
也就是说,你很接近。您忽略了这样一个事实,即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
嗯
declareUpdate();
const oldUri = "/test/doc1.xml";
const newUri = "/test/doc2.xml";
const oldDoc = cts.doc(oldUri);
const xslt = fn.head(xdmp.unquote(
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">\n\
<xsl:template match="foo/text()"><xsl:text>baz</xsl:text></xsl:template>\n\
<xsl:template match="@*|node()"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:template>\n\
</xsl:stylesheet>'));
const newDoc = xdmp.xsltEval(xslt, oldDoc.root);
xdmp.documentInsert(newUri, newDoc);
declareUpdate();
const oldUri = "/test/doc1.xml";
const newUri = "/test/doc2.xml";
const oldDoc = cts.doc(oldUri);
const xslt = fn.head(xdmp.unquote(
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">\n\
<xsl:param name="foo-val"/>\n\
<xsl:template match="foo/text()"><xsl:value-of select="$foo-val"/></xsl:template>\n\
<xsl:template match="@*|node()"><xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy></xsl:template>\n\
</xsl:stylesheet>'));
const newDoc = xdmp.xsltEval(xslt, oldDoc.root, {"foo-val": "baz"});
xdmp.documentInsert(newUri, 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