Search code examples
xquerymarklogic

How to return the full document using xdmp:node-replace()?


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 ?


Solution

  • 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.