Search code examples
marklogichttp-patch

Updating one or more values with MarkLogic patch


I'm trying to use MarkLogic's patch functionality (in version 9.0-9.1) to be able to edit one or more elements of a document. In the application, a user would have a screen that is populated with the original values and be able to edit one or more of the fields, then save the edits.

I have a document like this:

<root>
    <value1>original value</value1>
    <value2>original value</value2>
    <value3>original value</value3>
    <value4>original value</value4>
    <value5>original value</value5>
</root>

I'm trying to update it using this (with one or more values of edited content):

<rapi:patch xmlns:rapi="http://marklogic.com/rest-api">
    <rapi:replace-insert context="/root" select="value1">original value</rapi:replace-insert>
    <rapi:replace-insert context="/root" select="value2">original value</rapi:replace-insert>   
    <rapi:replace-insert context="/root" select="value3">edited content</rapi:replace-insert>
    <rapi:replace-insert context="/root" select="value4">original value</rapi:replace-insert>
    <rapi:replace-insert context="/root" select="value5">original value</rapi:replace-insert>   
</rapi:patch>

However, unless every field has new content, I get the following error:

2020-01-29 21:25:37.425 Info: Status 500: RESTAPI-INVALIDREQ: (err:FOER0000) Invalid request:  reason: invalid patch for uri /FILE0000026.xml: replace-insert without apply or content: /root

Is there a way to change one or more values in the same request without dynamically updating the patch to only apply to changed values?


Solution

  • The PATCH endpoint expects the replacements to be wrapped in a container element. If you want to insert plain text, you use <rapi:text>original value</rapi:text>, otherwise an element of your own choosing. Note that you are replacing the element, so you probably want to either wrap the contents in an element, or use the child elements as context, and text() as select. Something like:

      <rapi:patch xmlns:rapi="http://marklogic.com/rest-api">
        <rapi:replace-insert context="/root/value1" select="text()">
          <rapi:text>original value</rapi:text>
        </rapi:replace-insert>
        <rapi:replace-insert context="/root/value2" select="text()">
          <rapi:text>original value</rapi:text>
        </rapi:replace-insert>   
        <rapi:replace-insert context="/root/value3" select="text()">
          <rapi:text>edited content</rapi:text>
        </rapi:replace-insert>
        <rapi:replace-insert context="/root/value4" select="text()">
          <rapi:text>original value</rapi:text>
        </rapi:replace-insert>
        <rapi:replace-insert context="/root/value5" select="text()">
          <rapi:text>original value</rapi:text>
        </rapi:replace-insert>   
      </rapi:patch>
    

    See also our REST app dev guide: https://docs.marklogic.com/guide/rest-dev/documents#id_74834

    HTH!