从C#

时间:2019-06-07 09:57:31

标签: c# json json.net

我正在使用JsonDiffPatch.Diff()方法比较两个json对象,并得到以下JSON结构:

{
  "complexity": {
    "_t": "a",
    "0": {
      "phases": {
        "_t": "a",
        "0": {
          "activities": {
            "_t": "a",
            "_0": [
              {
                "name": "NAME",
                "sortId": 15,
                "isCritical": true,
                "url": "https://google.com",
                "processGroupName": "pgm",
                "isDeliverable": "no"
              },
              0,
              0
            ]
          }
        }
      }
    },
    "3": {
      "phases": {
        "_t": "a",
        "0": {
          "sortId": [
            55,
            0,
            0
          ]
        },
        "1": {
          "activities": {
            "_t": "a",
            "_0": [
              {
                "name": "SName",
                "sortId": 12,
                "isCritical": false,
                "url": "https://google.com",
                "processGroupName": "pgm",
                "isDeliverable": "Yes"
              },
              0,
              0
            ]
          }
        }
      }
    }
  }
}

我想要的结果是一个包含阶段列表的对象,该阶段包含活动列表。根据上面的JSON,我想要: 0 [阶段和相关活动] 3 [阶段和相关活动]

我写了以下代码:

List<JToken> tokens = diffJson.Children().Children().ToList();
        foreach (var token in tokens)
        {

            //Console.WriteLine(token.ToJson());
            var phases = token["0"].Children().Children();
            Console.WriteLine(phases.Count());
            var activities = phases["0"].Children().Children();
            Console.WriteLine();
        }

但这仅适用于“复杂性” [“ 0”]的第一组。但是如何将数据放入包含List的对象中。

我也尝试了以下代码:

JavaScriptSerializer serializer = new JavaScriptSerializer();
        dynamic item = serializer.Deserialize<object>(output);

有人可以帮助我理解如何将复杂的JSON反序列化为简单的对象吗?

我认为我将分阶段忽略“ _t”:“ a”对象并开始阅读活动(再次忽略“ _t”:“ a”对象)。让我看看我会多么成功。

预期的输出将创建以下类别的对象:

using System;
using System.Generic;
public class Difference {
public List<Phase> Phases { get; set; }
}

public class Phase {
    //For other properties like sortID
    public List<Dictionary<string, string>> Properties { get; set; }
    public List<Activity> Activites { get; set; }
}

public class Activity {
    public string name { get; set; }
    public int sortId { get; set; }
    public bool isCritical { get; set; }
    public string url { get; set; }
    public string processGroupName { get; set; }
    public string isDeliverable { get; set; }
}

下面是部分起作用的代码:

JavaScriptSerializer serializer = new JavaScriptSerializer();
        dynamic item = serializer.Deserialize<object>(output);
        foreach (KeyValuePair<string, dynamic> complexity in item["complexity"])
        {
            if (complexity.Key != "_t")
            {
                foreach (KeyValuePair<string, dynamic> phases in complexity.Value["phases"])
                {
                    if (phases.Key != "_t")
                        foreach (KeyValuePair<string, dynamic> activities in phases.Value["activities"])
                    {
                        Console.WriteLine(activities.Value);
                    }
                }
            }
        }

但是,当像sortId这样的简单键值出现在图片中时,此循环就会中断。

谢谢。

2 个答案:

答案 0 :(得分:1)

根据您在@MarcoSalemo答案中的评论中提到的内容,我已经修改了示例Json以适合您的要求Json现在由3子文档和2与1组成activity每个子文档,但最后一个具有2个activities和一个properties对象作为sortId的子文档:

示例JSON:

var jsonString = @"{
            'complexity': {
              '_t': 'a',
              '0': {
                'phases': {
                  '_t': 'a',
                  '0': {
                    'activities': {
                      '_t': 'a',
                      '_0': [
                        {
                          'name': 'NAME',
                          'sortId': 15,
                          'isCritical': true,
                          'url': 'https://google.com',
                          'processGroupName': 'pgm',
                          'isDeliverable': 'no'
                        },
                        0,
                        0
                      ]
                    }
                  }
                }
              },
              '1': {
                'phases': {
                  '_t': 'a',
                  '0': {
                    'activities': {
                      '_t': 'a',
                      '_0': [
                        {
                          'name': 'NAME1',
                          'sortId': 155,
                          'isCritical': true,
                          'url': 'https://google.com',
                          'processGroupName': 'pgm',
                          'isDeliverable': 'no'
                        },
                        0,
                        0
                      ]
                    }
                  }
                }
              },
              '3': {
                'phases': {
                  '_t': 'a',
                  '0': {
                    'sortId': [
                      55,
                      0,
                      0
                    ]
                  },
                  '1': {
                    'activities': {
                      '_t': 'a',
                      '_0': [
                        {
                          'name': 'SName',
                          'sortId': 12,
                          'isCritical': false,
                          'url': 'https://google.com',
                          'processGroupName': 'pgm',
                          'isDeliverable': 'Yes'
                        },
                        0,
                        0
                      ],
                      '_1': [
                        {
                          'name': 'SName1',
                          'sortId': 123,
                          'isCritical': false,
                          'url': 'https://google.com',
                          'processGroupName': 'pgm',
                          'isDeliverable': 'Yes'
                        },
                        0,
                        0
                      ]
                    }
                  }
                }
              }
            }
      }";

反序列化的实现方式为:

var jobj = JObject.Parse(jsonString);
List<Phase> Phases = new List<Phase>();                
var complexity = jobj.SelectToken("complexity");
var childrens = complexity.Children().ToList();

for (int i = 1; i < childrens.Count; i++)
{
    var activities = new List<Activity>();
    var _properties = new List<Dictionary<string, string>>();
    var child = childrens[i].Children();//getting all the sub-documets in the json
    foreach (var subChild in child)
    {
       var phases = subChild.SelectToken("phases").Children().ToList();//getting JTokens having key "phases"
       for (int j = 1; j < phases.Count; j++)
       {
          var phaseResult = phases[j].Children().ToList(); //getting all the children of the //phases JToken and itterating over them
          foreach (var item in phaseResult)
          {
             if (item["activities"] != null) //producing the "Activity(s)" object
             {
                var acts = item.SelectToken("activities").Children().ToList();
                for (int k = 1; k < acts.Count; k++)
                {
                   var act = acts[k].Children().ToList();
                   foreach (var entity in act)
                   {
                      var jarvalue = JArray.Parse(entity.ToString()).Children().ToArray()[0].ToString();
                      var objAct = JsonConvert.DeserializeObject<Activity>(jarvalue);
                      activities.Add(objAct);
                   }
                }
             }
             else
             {
                //if not Activity object than producing Properties object
                var _props = item.Children<JToken>().ToList();
                var nProeprties = new Dictionary<string, string>();
                foreach (var content in _props)
                {
                   var _contentProp = ((Newtonsoft.Json.Linq.JProperty)content); //converting the property object of JtokenType to JProperty to get the Name and JValue
                                    nProeprties.Add(_contentProp.Name, _contentProp.Value.ToString());                                        
                }

                _properties.Add(nProeprties);
             }
          }
       }
    }
    Phases.Add(new Phase { Activites = activities, Properties = _properties });//appending the extracted output to the mail object "Phases"
 }

根据上面的示例json,序列化的输出将如下所示:

JsonConvert.SerializeObject(Phases);

[
{
  "Properties":[

  ],
  "Activites":[
     {
        "name":"NAME",
        "sortId":15,
        "isCritical":true,
        "url":"https://google.com",
        "processGroupName":"pgm",
        "isDeliverable":"no"
     }
  ]
 },
 {
  "Properties":[

  ],
  "Activites":[
     {
        "name":"NAME1",
        "sortId":155,
        "isCritical":true,
        "url":"https://google.com",
        "processGroupName":"pgm",
        "isDeliverable":"no"
     }
  ]
 },
 {
  "Properties":[
     {
        "sortId":"[\r\n  55,\r\n  0,\r\n  0\r\n]"
     }
  ],
  "Activites":[
     {
        "name":"SName",
        "sortId":12,
        "isCritical":false,
        "url":"https://google.com",
        "processGroupName":"pgm",
        "isDeliverable":"Yes"
     },
     {
        "name":"SName1",
        "sortId":123,
        "isCritical":false,
        "url":"https://google.com",
        "processGroupName":"pgm",
        "isDeliverable":"Yes"
     }
  ]
 }
]

注意:

  • 我正在使用Newtonsoft.Json对json进行序列化/反序列化。
  • 这只是一种简单的方法,可以有很多(甚至更好)来实现您想要的目标。因此,请使用您的数据进行测试,并告诉我是否需要修改。

答案 1 :(得分:0)

使用dynamic并用JSON.NET反序列化json