Hello SO community :)!
I want to create method which will let user to edit (or add) JSON specific value or object (located in JSON by JSONPath). Below simple example what is on my mind. User always enters JSON, JSONPath and value/object to change. I'm using Json.NET library.
Method input {json, jsonpath, valuetoedit} || output {new json as string}
Example input:
{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
}
}
Example JSONPath:
$.store.book[*].author
Example value to change:
NewAuthorSpecifiedByUser
Output - new JSON where all authors will be changed to 'NewAuthorSpecifiedByUser'.
Is that even possible?
The 3rd party package json.net allows this to be done easily:
Parse the JSON into a LINQ to JSON hierarchy of JToken
tokens.
Select JSON values to modify via SelectTokens
using a query string in JSONPath syntax.
Using JToken.Replace()
replace the selected values with the new values. A new value can be serialized directly to a JToken
using JToken.FromObject()
.
Thus:
public static class JsonExtensions
{
public static JToken ReplacePath<T>(this JToken root, string path, T newValue)
{
if (root == null || path == null)
throw new ArgumentNullException();
foreach (var value in root.SelectTokens(path).ToList())
{
if (value == root)
root = JToken.FromObject(newValue);
else
value.Replace(JToken.FromObject(newValue));
}
return root;
}
public static string ReplacePath<T>(string jsonString, string path, T newValue)
{
return JToken.Parse(jsonString).ReplacePath(path, newValue).ToString();
}
}
Then use it like:
var newJsonAuthorString = JsonExtensions.ReplacePath(jsonString, @"$.store.book[*].author", "NewAuthorSpecifiedByUser");
Prototype fiddle. If you are going to allow the user to do a series of edits, it will likely be more efficient to keep your JSON in a JToken
hierarchy permanently rather that repeatedly converting from and to a string representation.
See also How to install JSON.NET using NuGet?.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With