Xquery 如何使用xdmp:node-replace()返回完整文档?
我有一个要求,在所有流程完成后,我需要最终返回完整的文档 我的上一条语句有一个Xquery 如何使用xdmp:node-replace()返回完整文档?,xquery,marklogic,Xquery,Marklogic,我有一个要求,在所有流程完成后,我需要最终返回完整的文档 我的上一条语句有一个xdmp:node-replace(),因此它返回一个空序列 在我的最终文档中,这些节点将被替换,但在第一次运行时,我无法在控制台上看到它们。当我第二次运行它时,我可以看到被替换的节点 下面是示例代码- abc.xml---> <root> <id>abcd</id> </root> let $doc := doc("abc.xml") (
xdmp:node-replace()
,因此它返回一个空序列
在我的最终文档中,这些节点将被替换,但在第一次运行时,我无法在控制台上看到它们。当我第二次运行它时,我可以看到被替换的节点
下面是示例代码-
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>
abc.xml--->
abcd
让$doc:=doc(“abc.xml”)
(:Let$doc有一个Id节点:)
让$replace:=xdmp:node replace($doc//id,1234)
返回$doc
实际输出-->
abcd
预期输出-->
1234
如果我将返回$replace
,那么它将给我空序列
我想在第一次运行时返回预期的输出
有什么建议吗?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版本“1.0-ml”;
xdmp:文档插入(“abc.xml”,
abcd
试验
);
让$doc:=doc(“abc.xml”)
让$update:=
1234
{$doc/root/name}
返回(
xdmp:文档插入(“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
)
xquery版本“1.0-ml”;
导入模块名称空间mem=”http://xqdev.com/in-mem-update“在mem update.xqy中的'/MarkLogic/appservices/utils/at';
让$doc:=doc(“abc.xml”)
让$updateDoc:=mem:node替换($doc//id,1234)
返回(
xdmp:节点替换($doc,$updatedoc),
$UpdateDoc
)
就性能而言,我认为mine和Mads Hansen的备选方案具有相同的性能特征。我会说选择你最喜欢的。
我在简单的更新用例中使用了我的方法,对于可能还涉及移动节点的更复杂的用例,我更愿意使用Mads Hansen的XSLT替代方案。您可以使用多语句事务,将写事务与读事务分开,以便可以看到更新
xquery version "1.0-ml";
xdmp:node-replace(doc("abc.xml")//id, <id>1234</id>)
;
xquery version "1.0-ml";
doc("abc.xml")
xquery版本“1.0-ml”;
xdmp:node replace(doc(“abc.xml”)//id,1234)
;
xquery版本“1.0-ml”;
文档(“abc.xml”)
另一种在内存中修改的替代方法是通过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 )
xquery版本“1.0-ml”;
声明变量$XSLT:=
1234
;
让$doc:=doc(“abc.xml”)
让$modified:=xdmp:xslt eval($xslt,$doc)
返回
(xdmp:节点替换($doc,$modified),$modified)
这个答案基本上是正确的。xdmp:node-replace()是一个不返回任何内容的状态设置函数。因此,这个答案相当于让$doc:=doc(“abc.xml”)返回xdmp:node replace($doc//id,1234)
,然后在新事务中,doc(“abc.xml”)
来查看更改的doc@Wargner迈克尔——谢谢你,这对我有帮助。所以基本上,在任何节点操作期间,只要我想返回文档结构,我就可以返回mem
文档?它不会产生性能问题?我认为返回内存中的文档没有问题。此外,这不应产生任何性能问题。将我的答案编辑为您可能想使用的另一个选项。@WagnerMichael谢谢!这很有帮助:)当我尝试使用分号代码>它给了我意外的标记语法错误并询问-你是说逗号,
否,a代码>。听起来你可能有一个太多的地方。您是否正在运行我发布的代码,或者您是否已应用到另一个可能有附加的模块
某处?@Mads——我正在将其应用于我的一个XQuery模块,但它没有任何代码>除了在顶部声明变量
和导入
名称空间之外。它说我们不能使用代码>XQuery中的运算符以终止一行