7.5 KiB
nlohmann::basic_json::patch_inplace
void patch_inplace(const basic_json& json_patch);
JSON Patch defines a JSON document structure for expressing a sequence of operations to apply to a JSON document. With this function, a JSON Patch is applied to the current JSON value by executing all operations from the patch. This function applies a JSON patch in place and returns void.
Parameters
json_patch (in) : JSON patch document
Exception safety
No guarantees, value may be corrupted by an unsuccessful patch operation.
Exceptions
- Throws
parse_error.104if the JSON patch does not consist of an array of objects. - Throws
parse_error.105if the JSON patch is malformed (e.g., mandatory attributes are missing); example:"operation 'add' must have member 'path'". - Throws
out_of_range.401if an array index is out of range. - Throws
parse_error.106if an array index in a "path" or "from" member begins with '0'; example:"array index '01' must not begin with '0'". - Throws
parse_error.107if a "path" or "from" member is not empty and does not begin with a slash (/); example:"JSON pointer must be empty or begin with '/' - was: 'a'". - Throws
parse_error.108if a tilde (~) in a "path" or "from" member is not followed by0or1; example:"escape character '~' must be followed with '0' or '1'". - Throws
parse_error.109if an array index in a "path" or "from" member is not a number; example:"array index 'foo' is not a number". - Throws
out_of_range.402if the array index-is used where an existing element is required (the "path" of "replace", the "from" of "move" and "copy"); example:"array index '-' (3) is out of range". - Throws
out_of_range.403if a JSON pointer inside the patch could not be resolved successfully in the current JSON value; example:"key baz not found". - Throws
out_of_range.404if a reference token of a JSON pointer inside the patch cannot be resolved, e.g.,-in a "remove" operation or1afor an array; example:"unresolved reference token '-'". - Throws
out_of_range.405if JSON pointer has no parent ("add", "remove", "move") - Throws
out_of_range.411if an "add" operation's target location has a parent that is neither an object nor an array. - Throws
out_of_range.413if a "remove" operation's target location has a parent that is neither an object nor an array. - Throws
out_of_range.414if a "move" operation's "from" location is a proper prefix of its "path" location. - Throws
other_error.501if "test" operation was unsuccessful.
Complexity
Linear in the size of the JSON value and the length of the JSON patch. As usually the patch affects only a fraction of the JSON value, the complexity can usually be neglected.
Notes
Unlike patch, patch_inplace applies the operation "in place" and no copy of the JSON value is created. That makes it faster for large documents by avoiding the copy. However, the JSON value might be corrupted if the function throws an exception.
Examples
Example: apply a JSON patch in place
The following code shows how a JSON patch is applied to a value.
#include <iostream>
#include <iomanip>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using namespace nlohmann::literals;
int main()
{
// the original document
json doc = R"(
{
"baz": "qux",
"foo": "bar"
}
)"_json;
// the patch
json patch = R"(
[
{ "op": "replace", "path": "/baz", "value": "boo" },
{ "op": "add", "path": "/hello", "value": ["world"] },
{ "op": "remove", "path": "/foo"}
]
)"_json;
// output original document
std::cout << "Before\n" << std::setw(4) << doc << std::endl;
// apply the patch
doc.patch_inplace(patch);
// output patched document
std::cout << "\nAfter\n" << std::setw(4) << doc << std::endl;
}
Output:
Before
{
"baz": "qux",
"foo": "bar"
}
After
{
"baz": "boo",
"hello": [
"world"
]
}
Example: out_of_range.403 exception with a partially applied patch
The following code shows a patch whose first operation succeeds and whose second operation fails. Because patch_inplace applies each operation directly to the value, the first operation's effect is still visible after the exception is caught, unlike patch.
#include <iostream>
#include <iomanip>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using namespace nlohmann::literals;
int main()
{
// the original document
json doc = R"(
{
"a": 1,
"b": 2
}
)"_json;
// a patch whose second operation fails
json patch = R"(
[
{ "op": "replace", "path": "/a", "value": 99 },
{ "op": "remove", "path": "/nonexistent" }
]
)"_json;
// exception out_of_range.403
try
{
doc.patch_inplace(patch);
}
catch (const json::out_of_range& e)
{
std::cout << e.what() << '\n';
}
// the first operation has already been applied to doc
std::cout << std::setw(4) << doc << std::endl;
}
Output:
[json.exception.out_of_range.403] key 'nonexistent' not found
{
"a": 99,
"b": 2
}
See also
- RFC 6902 (JSON Patch)
- RFC 6901 (JSON Pointer)
- patch applies a JSON Patch
- merge_patch applies a JSON Merge Patch
Version history
- Added in version 3.11.0.
- Added
out_of_range.411and stopped relying on an internal assertion when an "add" operation's target location has a non-object/non-array parent in version 3.13.0 unreleased. - Added
out_of_range.413and stopped silently ignoring a "remove" operation whose target location has a non-object/non-array parent in version 3.13.0 unreleased. - Added
out_of_range.414and rejected a "move" operation whose "from" location is a proper prefix of its "path" location instead of silently producing a corrupted result in version 3.13.0 unreleased.