I have a requirement where i need to return the full document at last after all the process completes.
My Last statement is having an xdmp:node-replace()
and hence it is returning an empty sequence
.
The nodes are getting replaced in my final document but i am not able to see them on console in 1st run. When i am running it second time then i can able to see the replaced node.
Here is the sample code-
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>
If i will return $replace
then it will give me empty sequence
I want to return the expected output in 1st run
Any Suggestions ?
xdmp:node-replace
replaces nodes in database, not in-memory. Also you cannot see database updates before a commit.
A simple solution would be to create a updated in-memory document and return that.
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
)
Edit:
Alternative using a in-memory replace function:
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
)
Performance-wise i think mine and Mads Hansen's alternatives share the same performance characteristics. I'd say choose whatever you like most. I have used my approach for simple update use cases alot, for more complicated use cases which might also involve moving nodes or so, i'd rather use Mads Hansen's XSLT alternative.