如何使用xdmp:node-replace()返回完整文档?

时间:2018-11-29 10:49:25

标签: xquery marklogic

我有一个要求,我需要在所有过程完成后最后返回完整的文档。

我的最后一条语句有一个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

我想在第一次运行中返回预期的输出

有什么建议吗?

3 个答案:

答案 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")