我有一个要求,我需要在所有过程完成后最后返回完整的文档。
我的最后一条语句有一个xdmp:node-replace()
,因此它返回了一个empty sequence
。
我的最终文档中的节点已被替换,但是第一次运行时我无法在控制台上看到它们。当我第二次运行它时,我可以看到替换的节点。
这是示例代码-
abc.xml--->
<root>
<id>abcd</id>
</root>
let $doc := doc("abc.xml")
(: Let $doc is having an Id node :)
let $replace := xdmp:node-replace($doc//id,<id>1234</id>)
return $doc
Actual Output-->
<root>
<id>abcd</id>
</root>
Expected Output-->
<root>
<id>1234</id>
</root>
如果我将返回$replace
,那么它将给我empty sequence
我想在第一次运行中返回预期的输出
有什么建议吗?
答案 0 :(得分:3)
xdmp:node-replace
替换数据库中的节点,而不是内存中的节点。另外,您在提交之前也看不到数据库更新。
一个简单的解决方案是创建一个更新的内存中文档并将其返回。
xquery version "1.0-ml";
xdmp:document-insert("abc.xml",
<root>
<id>abcd</id>
<name>Test</name>
</root>
);
let $doc := doc("abc.xml")
let $update :=
<root>
<id>1234</id>
{$doc/root/name}
</root>
return (
xdmp:document-insert("abc.xml", $update),
$update
)
编辑:
使用内存替换功能的替代方法:
xquery version "1.0-ml";
import module namespace mem = "http://xqdev.com/in-mem-update" at '/MarkLogic/appservices/utils/in-mem-update.xqy';
let $doc := doc("abc.xml")
let $updatedDoc := mem:node-replace($doc//id, <id>1234</id>)
return (
xdmp:node-replace($doc, $updatedDoc),
$updatedDoc
)
在性能方面,我认为我的产品和Mads Hansen的替代产品具有相同的性能特征。我会说选择最喜欢的东西。 我将自己的方法用于很多简单的更新用例,对于更复杂的用例(也可能涉及移动节点),我宁愿使用Mads Hansen的XSLT替代方案。
答案 1 :(得分:2)
另一个修改内存的方法是通过XSLT。使用身份转换,创建模板以匹配要更改的节点:
xquery version "1.0-ml";
declare variable $XSLT :=
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="id/text()">
<xsl:text>1234</xsl:text>
</xsl:template>
</xsl:stylesheet>;
let $doc := doc("abc.xml")
let $modified := xdmp:xslt-eval($XSLT, $doc)
return
( xdmp:node-replace($doc, $modified), $modified )
答案 2 :(得分:1)
您可以使用多语句事务using a semi-colon将写事务与读事务分开,以便可以看到更新。
xquery version "1.0-ml";
xdmp:node-replace(doc("abc.xml")//id, <id>1234</id>)
;
xquery version "1.0-ml";
doc("abc.xml")