Fosk
Fosk

Reputation: 23

How to traverse the complex nested Json in C# and append the some set of values in the same Json

I need to traverse the below and form the final output with an additional set of values added in the same JSON model. Please help me how to add as the data contains recursively.

Order of Keys should not be modified. The final output should be the same format. I would like to deserialize this JSON into some classes, update the some more data and then later serialize it back to JSON. How can we do it?

Read from Json File: Input:

      {
  "id" : "abv.123",
  "developName" : "ABV.123",
  "pay25" : {
    "0" : {
      "data" : "group35",
      "divison" : 0,
      "pay25" : {
        "0" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "name33"        
        }
      }
    },
    "1" : {
      "data" : "group35",
      "divison" : 0,
      "pay25" : {
        "0" : {
          "data" : "group35",
          "divison" : 0,
          "pay25" : {
            "0" : {
              "data" : "label",
              "divison" : 0,
              "text" : "name55",
              "color1" : "green"
            }
          }
        },
        "1" : {
          "data" : "group35",
          "divison" : 0,
          "pay25" : {
            "0" : {
              "data" : "divisiondata",
              "divison" : 0,
              "divName" : "fab125"

            },
            "1" : {
              "data" : "divisiondata",
              "divison" : 0,
              "divName" : "gbt333"
            },
            "2" : {
              "data" : "divisiondata",
              "divison" : 0,
              "divName" : "test53"
            },
            "3" : {
              "data" : "divisiondata",
              "divison" : 0,
              "divName" : "test55"
            },
            "4" : {
              "data" : "divisiondata",
              "divison" : 0,
              "divName" : "teds422"
            },
            "5" : {
              "data" : "divisiondata",
              "divison" : 0,
              "divName" : "test66"
            },
            "6" : {
              "data" : "divisiondata",
              "divison" : 0,
              "divName" : "test982"
            },
            "7" : {
              "data" : "divisiondata",
              "divison" : 0,
              "divName" : "test322"
            },
            "8" : {
              "data" : "divisiondata",
              "divison" : 0,
              "divName" : "test633"
            },
            "9" : {
              "data" : "divisiondata",
              "divison" : 0,
              "divName" : "test622"
            },
            "10" : {
              "data" : "divisiondata",
              "divison" : 0,
              "divName" : "test733"
            },
            "11" : {
              "data" : "divisiondata",
              "divison" : 0,
              "divName" : "test71"
            }
          }
        }
      }
    },
    "2" : {
      "data" : "group35",
      "divison" : 0,
      "pay25" : {
        "0" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "test9134234",
          "deps1" : [ {
            "datadiv123" : [ "1", "2" ],
            "value" : true
          } ]
        },
        "1" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "test898932"
        },
        "2" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "tewst432"
        }
      }
    },
    "3" : {
      "data" : "group35",
      "divison" : 0,
      "pay25" : {
        "0" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "test352322",
           "deps1" : [ {
            "datadiv123" : [ "test", "tesstt" ],
            "value" : true
          } ]
        },
        "1" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "test523432"
        },
        "2" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "test634fdg"
        },
        "3" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "tssg32432",
          "validators" : [ {
            "data" : "integer"
          } ]
        },
        "4" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "test1111"
        },
        "5" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "test2222"
        }
      }
    },
    "4" : {
      "data" : "group35",
      "divison" : 0,
      "pay25" : {
        "0" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "test55632"
        }
      }
    },
    "5" : {
      "data" : "dynamicgrouptable",
      "operation" : [ "add", "delete" ],
      "dynamicValue" : {
        "0" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "test953312"
        },
        "1" : {
         "data" : "divisiondata",
          "divison" : 0,
          "divName" : "test953312622"
        },
        "2" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "test9533126499"
        },
        "3" : {
          "data" : "divisiondata",
          "divison" : 0,
          "divName" : "test953312644"
        }
      }
    }
  }
}

Read the additional set of values from this JSON:

    {
    "name33": {
        "def1": "Value 1",
        "tip3": "Tip 53",
        "disp3": "develop 1",
        "path" : "Displayname"

    },
    "fab125": {
        "def1": "Value 5",
        "tip3": "strr11",
        "disp3": "develop 2",
        "path" : "Displayname"
    },
    "test322": {
        "def1": "Value 2",
        "tip3": "dev 53",
        "disp3": "develop 3",
        "path" : "Displayname"

    },
    {....},
{.....},
"test953312": {
        "def1": "Value 21",
        "tip3": "dev 5311",
        "disp3": "develop 334",
        "path" : "Displayname"

    },
    "test953312622": {
        "def1": "Value 212",
        "tip3": "dev 53222",
        "disp3": "develop 22113",
        "path" : "Displayname"

    },
    {....}

}

The output should be merged with both json without changing the order of data:

Upvotes: 2

Views: 349

Answers (2)

Epic Chen
Epic Chen

Reputation: 1382

Solution 1:

You could use Newtonsoft.Json.Linq of Newtonsoft.Json to trevasal the data. Since your data is not regular, deserialize it is more complicated. It may not output extra fields.

   //deserialize
   JObject jObj = JObject.Parse(jsonString);
   JObject idObj = (JObject)jObj["id"];
   JObject idObj0 = (JObject)idObj["0"]["id"]["0"]; // 0 can replace to N, loop can deal with it.
   idObj0.add("value", "ewr");
   idObj0.add("type", "bool");
   //serialize
   string resultJsonString = jObj.ToString();

Reference: Json.NET Modifying JSON

Solution 2:

If you prefer to deserialize into a class. you could use the native library System.Text.Json in .Net 5 or .Net Core 3.1

      public class Model
      {
          public string reports {get; set;};
          public Dictionary<string, IdModel> id {get; set;};
      }

      public class IdModel
      {
           [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
           public string data {get; set;}
           [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
           public string text {get; set;}
           [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
           public string name {get; set;}
           [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
           public string display {get; set;}
           [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
           public string value {get; set;}
           [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
           public string type {get; set;}
           [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
           public Dictionary<string, IdModel> id {get; set;};
      }

      var data = JsonSerializer.Deserialize<Model>(jsonString);
      data.id["0"].id["0"].value = "ewr";
      data.id["0"].id["0"].type = "bool";
      .......
      string resultJsonString = JsonSerializer.Serialize<Model>(data);

Reference: How to serialize and deserialize (marshal and unmarshal) JSON in .NET

I will choose solution 1, because of the complicated data.

Here is the code you could reference

     using Newtonsoft.Json.Linq;

     var inputJObject = JObject.Parse(jsonString);
     var appendDataJObject = JObject.Parse(appendDataString);

     FindAndReplace(inputJObject, appendDataJObject);

     string resultString = inputJObject.ToString();

     public static void FindAndReplace(
          JObject input, 
          JObject appendData, 
          string keyName = "pay25", 
          string toReplaceFieldName = "divName")
     {
          foreach (var targetKey in ((JObject)input[keyName]))
          {
               var targetJObject = (JObject)targetKey.Value;

               //check whether there is pay25 property in child, if yes, search child recursively
               if (targetJObject.ContainsKey(keyName))
               {
                    FindAndReplace(targetJObject, appendData);
               }
               else
               {
                    //if no, check divName property existence
                    if (targetJObject.ContainsKey(toReplaceFieldName))
                    {
                         string divName = (string)targetJObject[toReplaceFieldName];
                         //check whether there is data has key = divName
                         if (appendData.ContainsKey(divName))
                         {
                              //append data
                              foreach (var data in (JObject)appendData[divName])
                              {
                                   targetJObject.Add(data.Key, data.Value);
                              }
                          }
                     }
                }
           }
      }

Finally, I think it is a question of how to replace data recursively.

Upvotes: 1

Well you can use Newtonsoft.Json it's, it's the most used library in C#. So, first of all, you would need to create a model for what your data. I would assume would look like this:

public class MyModel{
public List<MyModel> id {get;set;}
.....
}
public class MyTopLevelModel : MyModel{
public string reports{get;set;}
}

So you can do this:

MyTopLevelModel myTopLevelModel = JsonConvert.DeserializeObject<MyTopLevelModel>(json);
//then get the place where you want to place the extra data like 
myTopLevelModel.id[0].id[0].value = "whatever"

After that you can use

var result = JsonConvert.SerializeObject(myTopLevelModel);

Upvotes: 1

Related Questions