title: How to dynamically reference nodes in xdmp:node-replace in MarkLogic?
body: <p>In my function <strong>update-replace</strong>, I am trying to dynamically replace an XML node in one of my XML data source files in MarkLogic by calling <code>xdmp:node-replace</code> like below:</p>
  
  <pre><code>declare function update-lib:update-rec($doc as xs:string, $path as xs:string, $country as xs:string, $name as xs:string, $population as xs:integer, $latitude as xs:decimal, $longitude as xs:decimal) as document-node() {
      (: read lock acquired :)
      fn:doc($doc),
  
      xdmp:node-replace(fn:doc($doc)/$path,
          &lt;city&gt;
              &lt;country&gt;{$country}&lt;/country&gt;
              &lt;name&gt;{$name}&lt;/name&gt;
              &lt;population&gt;{$population}&lt;/population&gt;
              &lt;latitude&gt;{$latitude}&lt;/latitude&gt;
              &lt;longitude&gt;{$longitude}&lt;/longitude&gt;
          &lt;/city&gt;
      ),
  
  
      (: after the following statement, txn ends and locks released :)
      xdmp:commit()
  };
  </code></pre>
  
  <p>The function takes 7 arguments with the 1st arg being path to the XML source file, the 2nd being path inside the XML file to the node to be updated and the rest corresponds to the child element values.</p>
  
  <p>When I call <code>xdmp:node-replace</code> to update data, I encounter the following error:</p>
  
  <blockquote>
    <p>500 Internal Server Error</p>
    
    <p>XDMP-ARGTYPE: (err:XPTY0004) xdmp:node-replace("/cities/city[3961]",
    JPMiyoshi56958)
    -- arg1 is not of type node() ...</p>
  </blockquote>
  
  <p>So I decided to have arg1 evaluated to ensure that node() gets passed as the 1st arg of node-replace:</p>
  
  <pre><code>xdmp:node-replace(xdmp:eval(fn:doc($doc)/$path),
      &lt;city&gt;
          &lt;country&gt;{$country}&lt;/country&gt;
          &lt;name&gt;{$name}&lt;/name&gt;
          &lt;population&gt;{$population}&lt;/population&gt;
          &lt;latitude&gt;{$latitude}&lt;/latitude&gt;
          &lt;longitude&gt;{$longitude}&lt;/longitude&gt;
      &lt;/city&gt;
  ),
  </code></pre>
  
  <p>Now I receive the below error instead:</p>
  
  <blockquote>
    <p>XDMP-UPEXTNODES:
    xdmp:node-replace(fn:doc("/content/Users/Tako/Sites/MarkLogic/xml/worldcities/import/cities1000_02.xml")/cities/city[3961],
    JPMiyoshi56958)
    -- Cannot update external nodes ...</p>
  </blockquote>
  
  <p>After a little googling, I've found this.  It sounds like an issue with <code>xdmp:eval</code> and its context:</p>
  
  <p><a href="http://developer.marklogic.com/pipermail/general/2008-September/001753.html" rel="nofollow">http://developer.marklogic.com/pipermail/general/2008-September/001753.html</a></p>
  
  <p>I tried the workaround suggested here using <code>fn:concat</code> to have everything constructed as a string including <code>xdmp:node-replace</code> and evaluating the whole statement.</p>
  
  <pre><code>xdmp:eval(fn:concat('xdmp:node-replace(fn:doc("', $doc, '")', $path,
      ', ', '&lt;city&gt;&lt;country&gt;',$country,'&lt;/country&gt;&lt;name&gt;',$name,'&lt;/name&gt;&lt;population&gt;',$population,'&lt;/population&gt;&lt;latitude&gt;',$latitude,'&lt;/latitude&gt;&lt;longitude&gt;',$longitude,'&lt;/longitude&gt;&lt;/city&gt;', ')')),
  </code></pre>
  
  <p>The application sits and waits for a very long time before timing out when I tried this.
  500 Internal Server Error</p>
  
  <blockquote>
    <p>SVC-EXTIME:
    xdmp:node-replace(fn:doc("/content/Users/Tako/Sites/MarkLogic/xml/worldcities/import/cities1000_17.xml")/cities/city[3961],
    JPMiyoshi56958)
    -- Time limit exceeded ...</p>
  </blockquote>
  
  <p>All I want to do is to dynamically reference the XML file and the nodes to be updated and update the node with the info passed in.  I must be overlooking something very fundamental or doing this completely wrong.</p>
  
  <p>Could someone please shed light on this?</p>