我正在使用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这样的简单键值出现在图片中时,此循环就会中断。
谢谢。
答案 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"
}
]
}
]
注意:
答案 1 :(得分:0)
使用dynamic
并用JSON.NET
反序列化json