Reputation: 6868
Below is my JSON:
[
{
"name": "Node-1",
"flag": true,
"myObj": {
region: {
info: {
name: null,
infoFlag: false,
}
}
},
"nodes": [
{
"name": "Node-1-1",
"flag": true,
"myObj": {
region: {
info: {
name: "abc",
infoFlag: false,
}
}
},
"nodes": [
{
"name": "Node-1-1-1",
"flag": true,
"myObj": {
region: {
info: {
name: "xyz",
infoFlag: false,
}
}
},
"nodes": [
]
}
]
}
]
}
]
I want to update two properties of my above JSON string with following rule :
Flag : I want to blindly update this property to false
.
infoFlag: If name
property of info
is null
then I want to update infoFlag
to true
else false
if it is not null
.
So after updating my JSON with these rules I want to have that JSON as a string.
Note: I don't want to deserialize and then update property based on above two rules as because my JSON has lots of properties for which I don't want to create classes, so I am looking for something which will work without deserializing with class.
This is how I am trying to do it:
string json = "MyJson";
var temp = JArray.Parse(json);
temp.Descendants()
.OfType<JProperty>()
json = temp.ToString();
But here I am not getting as how to traverse my JSON recursively; as you can see I have recursive structure like below :
Node-1
Node-1-1
Node-1-1-1
Upvotes: 1
Views: 5097
Reputation: 205619
Json.NET allows you to treat its internal objects representing the JSON content as dynamic
, which makes the task in question no harder than using regular typed objects.
The only kind of tough problem is the recursive object structure (the nodes
array), but that's not a JSON or dynamic
specific problem, and can be solved in many ways - the obvious recursive method or with my preferable tree flattening enumeration (the Expand
method from my answer to How to flatten tree via LINQ?).
With that being said, the solution could be like this:
var array = JArray.Parse(json);
var nodes = array.Cast<dynamic>().Expand(x => x.nodes);
foreach (var node in nodes)
{
node.flag = true;
var info = node.myObj.region.info;
info.infoFlag = (info.name == null);
}
var newJson = array.ToString();
Upvotes: 2
Reputation: 784
If I have understood your needs this code is pretty verbose and not so elegant but works:
JArray temp = JArray.Parse(json);
foreach (JToken tk in temp.Descendants())
{
if (tk.Type == JTokenType.Property)
{
JProperty p = tk as JProperty;
if (p.Name == "flag")
{
if ((bool)p.Value.ToObject(typeof(bool)) == true)
p.Value = false;
}
if ((p.Name == "info") && p.HasValues)
{
bool flag = false;
foreach (JToken tkk in p.Descendants())
{
if (tkk.Type == JTokenType.Property)
{
JProperty pp = tkk as JProperty;
if ((pp.Name == "name") && (pp.Value.Type == JTokenType.Null))
{
flag = true;
}
if ((pp.Name == "infoFlag"))
{
pp.Value = (flag == true) ? true : false;
}
}
}
}
}
}
json = temp.ToString();
This is the resulting output:
[
{
"name": "Node-1",
"flag": false,
"myObj": {
"region": {
"info": {
"name": null,
"infoFlag": true
}
}
},
"nodes": [
{
"name": "Node-1-1",
"flag": false,
"myObj": {
"region": {
"info": {
"name": "abc",
"infoFlag": false
}
}
},
"nodes": [
{
"name": "Node-1-1-1",
"flag": false,
"myObj": {
"region": {
"info": {
"name": "xyz",
"infoFlag": false
}
}
},
"nodes": []
}
]
}
]
}
]
Upvotes: 2