In my function update-replace, I am trying to dynamically replace an XML node in one of my XML data source files in MarkLogic by calling xdmp:node-replace like below:
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,
<city>
<country>{$country}</country>
<name>{$name}</name>
<population>{$population}</population>
<latitude>{$latitude}</latitude>
<longitude>{$longitude}</longitude>
</city>
),
(: after the following statement, txn ends and locks released :)
xdmp:commit()
};
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.
When I call xdmp:node-replace to update data, I encounter the following error:
500 Internal Server Error
XDMP-ARGTYPE: (err:XPTY0004) xdmp:node-replace("/cities/city[3961]", JPMiyoshi56958) -- arg1 is not of type node() ...
So I decided to have arg1 evaluated to ensure that node() gets passed as the 1st arg of node-replace:
xdmp:node-replace(xdmp:eval(fn:doc($doc)/$path),
<city>
<country>{$country}</country>
<name>{$name}</name>
<population>{$population}</population>
<latitude>{$latitude}</latitude>
<longitude>{$longitude}</longitude>
</city>
),
Now I receive the below error instead:
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 ...
After a little googling, I've found this. It sounds like an issue with xdmp:eval and its context:
http://developer.marklogic.com/pipermail/general/2008-September/001753.html
I tried the workaround suggested here using fn:concat to have everything constructed as a string including xdmp:node-replace and evaluating the whole statement.
xdmp:eval(fn:concat('xdmp:node-replace(fn:doc("', $doc, '")', $path,
', ', '<city><country>',$country,'</country><name>',$name,'</name><population>',$population,'</population><latitude>',$latitude,'</latitude><longitude>',$longitude,'</longitude></city>', ')')),
The application sits and waits for a very long time before timing out when I tried this. 500 Internal Server Error
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 ...
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.
Could someone please shed light on this?