c# - 如何在 C# 中遍历复杂的嵌套 Json 并将一组值附加到同一个 Json 中

标签 c# json .net recursion json.net

我需要遍历下面的内容并在同一 JSON 模型中添加一组附加值来形成最终输出。请帮助我如何添加数据,因为数据包含递归。

不应修改键的顺序。最终输出应该是相同的格式。 我想将此 JSON 反序列化为一些类,更新更多数据,然后将其序列化回 JSON。我们怎样才能做到呢?

从 Json 文件中读取: 输入:

      {
  "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"
        }
      }
    }
  }
}

从此 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"

    },
    {....}

}

输出应该与两个 json 合并,而不改变数据的顺序:

最佳答案

解决方案1:

您可以使用Newtonsoft.JsonNewtonsoft.Json.Linq来篡改数据。由于您的数据不规则,因此反序列化会更加复杂。它可能不会输出额外的字段。

   //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();

引用:Json.NET Modifying JSON

解决方案2:

如果您更喜欢反序列化为类。您可以在.Net 5或.Net Core 3.1中使用 native 库System.Text.Json

      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);

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

由于数据复杂,我会选择方案1。

这是您可以引用的代码

     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);
                              }
                          }
                     }
                }
           }
      }

最后我觉得是一个如何递归替换数据的问题。

关于c# - 如何在 C# 中遍历复杂的嵌套 Json 并将一组值附加到同一个 Json 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67735183/

相关文章:

c# - Fluent NHibernate 忽略 ClassMap 中的属性,使用 FluentMappings

javascript - Strapi:获取深度嵌套关系的所有嵌套属性

java - 从 2.10 升级时 Jackson 序列化失败(InvalidDefinitionException : Type id handling not implemented for type java. lang.Object)

c# - 使用 Dapper 从 MySql 映射日期字段时出现 InvalidCastException

.net - 从解决方案sln的所有csproj项目中阅读引用文献列表(以编程方式)

java - RAM 内存重新分配 - Windows 和 Linux

c# - 类型转换 Excel 单元格

c# - Console.WriteLine 在 ASP.net 生产环境中去哪里?

javascript - Angular 翻译问题

c# - 我可以在 Linux 上为 .NET Core (C#) 运行 SonarQube 代码分析吗?