5.6 KiB
nlohmann::basic_json::merge_patch
void merge_patch(const basic_json& apply_patch);
The merge patch format is primarily intended for use with the HTTP PATCH method as a means of describing a set of modifications to a target resource's content. This function applies a merge patch to the current JSON value.
The function implements the following algorithm from Section 2 of RFC 7396 (JSON Merge Patch):
define MergePatch(Target, Patch):
if Patch is an Object:
if Target is not an Object:
Target = {} // Ignore the contents and set it to an empty Object
for each Name/Value pair in Patch:
if Value is null:
if Name exists in Target:
remove the Name/Value pair from Target
else:
Target[Name] = MergePatch(Target[Name], Value)
return Target
else:
return Patch
Thereby, Target is the current object; that is, the patch is applied to the current value.
Parameters
apply_patch(in)- the patch to apply
Exception safety
Basic guarantee: if an exception is thrown during the operation, the JSON value may be partially modified.
Complexity
Linear in the total number of values (including nested ones) in apply_patch, times the cost of a key-based object
operation (looking up, adding, or erasing a member): logarithmic for json, and linear for
ordered_json (see ordered_map complexity). For
ordered_json, patching an object that has n members with a patch that has m members therefore takes O(n·m). The
cost also includes one copy of apply_patch (see the notes below).
Notes
apply_patchmay be#!cpp *thisitself or refer to a value contained in#!cpp *this(for example, a subobject returned by#!cpp (*this)[key]); it is read as it was whenmerge_patch()was called, before any modification of#!cpp *this. To make this possible, the function copiesapply_patchbefore it modifies#!cpp *this, so the cost includes one copy of the patch.- A merge patch uses
#!json nullto remove a member, so it cannot set a member to#!json null: applying#!json {"a":null}to#!json {"a":1}gives#!json {}. - Arrays are not merged: an array in the patch replaces the target value as a whole, and a
#!json nullinside an array is kept as an element.#!json nullmembers of the target that the patch does not mention are preserved. - A
#!json nullin the patch only removes a member; it does not prevent the creation of the enclosing objects. Applying#!json {"a":{"b":null}}to#!json {}gives#!json {"a":{}}(see example 15 in Appendix A of the RFC). - If
apply_patchis not an object, it replaces the target as a whole. In particular, a#!json nullpatch turns the target into#!json null. Ifapply_patchis an object and the target is not, the target is first replaced by an empty object, so applying#!json {}to#!json 1gives#!json {}. - A merge patch cannot express every change; for example, it cannot reorder array elements or remove a specific array
element. Use JSON Patch (RFC 6902) for that.
merge_diffhas a matching limitation, see its notes. - A discarded value is treated like any other non-object value: a discarded
apply_patchturns the target into a discarded value, and an object patch replaces a discarded target by an object as described above.
Examples
??? example
The following code shows how a JSON Merge Patch is applied to a JSON document.
```cpp
#include <iostream>
#include <nlohmann/json.hpp>
#include <iomanip> // for std::setw
using nlohmann::json;
using namespace nlohmann::literals;
int main()
{
// the original document
json document = R"({
"title": "Goodbye!",
"author": {
"givenName": "John",
"familyName": "Doe"
},
"tags": [
"example",
"sample"
],
"content": "This will be unchanged"
})"_json;
// the patch
json patch = R"({
"title": "Hello!",
"phoneNumber": "+01-123-456-7890",
"author": {
"familyName": null
},
"tags": [
"example"
]
})"_json;
// apply the patch
document.merge_patch(patch);
// output original and patched document
std::cout << std::setw(4) << document << '\n';
}
```
Output:
```json
{
"author": {
"givenName": "John"
},
"content": "This will be unchanged",
"phoneNumber": "+01-123-456-7890",
"tags": [
"example"
],
"title": "Hello!"
}
```
See also
- RFC 7396 (JSON Merge Patch) - specification of JSON Merge Patch
patch- apply a JSON patchmerge_diff- creates a diff as a JSON Merge Patch- JSON Merge Patch - the article on JSON Merge Patch
Version history
- Added in version 3.1.0.
- Fixed use of freed or relocated memory when
apply_patchis#!cpp *thisor refers to a value contained in#!cpp *this, in version 3.13.0.