我想一般地展平一些json,以便我可以使用c#转换为数据表并绑定到datagrid
考虑到我不知道我要下降多少级别,最好的控制方式是什么?
例如
{ “ appointmentid”:4 “ policyid”:1, “ guid”:“ 00000000-0000-0000-0000-000000000000”, “ number”:“ 1234567890”, “ ampm”:“ false”, “ date”:“ 2015-09-08T00:00:00”, “车辆”:{ “ id”:1 “ guid”:“ 00000000-0000-0000-0000-000000000000”, “ make”:null, “型号”:null }, “安装程序”:{ “ installerid”:“ 1”, “ name”:“安装程序1”, “联系人”:“ qwerty”, “ qascore”:“ 0”, “ address1”:“ qwerty”, “ address2”:“ qwerty”, “ address3”:null, “ address4”:null, “ city”:“ qwertyu”, “ county”:“ qwertyu”, “邮政编码”:“ asdfghj”, “ country”:“ GB”, “ email”:“ asdfghj”, “ web”:“ asdfghjk”, “已存档”:false }, “安装”:[ { “ installationid”:6 “ installationstatus”:{ “ installationstatusid”:4 “ installationstatus”:“失败” }, “无效”:true }, { “ installationid”:7 “ installationstatus”:{ “ installationstatusid”:1 “ installationstatus”:“ NEW” }, “无效”:false } ], “已存档”:false }
我想扩展它(我想我可以对转换后的数据表进行迭代),而不是installations.1.installationid,我将得到installationid1。
因为我要在网格中显示结果数据表,所以我想保持列名友好。
您可以使用Json.Net的LINQ-to-JSON API将数据解析为JToken结构。从那里,您可以使用递归帮助器方法来遍历结构并将其展平到Dictionary<string, object>键是原始JSON中每个值的“路径”的位置。我会这样写:
JToken
Dictionary<string, object>
public class JsonHelper { public static Dictionary<string, object> DeserializeAndFlatten(string json) { Dictionary<string, object> dict = new Dictionary<string, object>(); JToken token = JToken.Parse(json); FillDictionaryFromJToken(dict, token, ""); return dict; } private static void FillDictionaryFromJToken(Dictionary<string, object> dict, JToken token, string prefix) { switch (token.Type) { case JTokenType.Object: foreach (JProperty prop in token.Children<JProperty>()) { FillDictionaryFromJToken(dict, prop.Value, Join(prefix, prop.Name)); } break; case JTokenType.Array: int index = 0; foreach (JToken value in token.Children()) { FillDictionaryFromJToken(dict, value, Join(prefix, index.ToString())); index++; } break; default: dict.Add(prefix, ((JValue)token).Value); break; } } private static string Join(string prefix, string name) { return (string.IsNullOrEmpty(prefix) ? name : prefix + "." + name); } }
将此DeserializeAndFlatten方法与JSON结合使用,最终会得到像这样的键值对:
DeserializeAndFlatten
appointmentid: 4 policyid: 1 guid: 00000000-0000-0000-0000-000000000000 number: 1234567890 ampm: false date: 9/8/2015 12:00:00 AM vehicle.id: 1 vehicle.guid: 00000000-0000-0000-0000-000000000000 vehicle.make: vehicle.model: installer.installerid: 1 installer.name: Installer 1 installer.contact: qwerty installer.qascore: 0 installer.address1: qwerty installer.address2: qwerty installer.address3: installer.address4: installer.city: qwertyu installer.county: qwertyu installer.postcode: asdfghj installer.country: GB installer.email: asdfghj installer.web: asdfghjk installer.archived: False installations.0.installationid: 6 installations.0.installationstatus.installationstatusid: 4 installations.0.installationstatus.installationstatus: FAIL installations.0.isactive: True installations.1.installationid: 7 installations.1.installationstatus.installationstatusid: 1 installations.1.installationstatus.installationstatus: NEW installations.1.isactive: False archived: False
如果您希望使这些按键更人性化,则可以使用一些字符串操作来将其缩减。也许是这样的:
var dict = JsonHelper.DeserializeAndFlatten(json); foreach (var kvp in dict) { int i = kvp.Key.LastIndexOf("."); string key = (i > -1 ? kvp.Key.Substring(i + 1) : kvp.Key); Match m = Regex.Match(kvp.Key, @"\.([0-9]+)\."); if (m.Success) key += m.Groups[1].Value; Console.WriteLine(key + ": " + kvp.Value); }
那会给你这个输出:
appointmentid: 4 policyid: 1 guid: 00000000-0000-0000-0000-000000000000 number: 1234567890 ampm: false date: 9/8/2015 12:00:00 AM id: 1 guid: 00000000-0000-0000-0000-000000000000 make: model: installerid: 1 name: Installer 1 contact: qwerty qascore: 0 address1: qwerty address2: qwerty address3: address4: city: qwertyu county: qwertyu postcode: asdfghj country: GB email: asdfghj web: asdfghjk archived: False installationid0: 6 installationstatusid0: 4 installationstatus0: FAIL isactive0: True installationid1: 7 installationstatusid1: 1 installationstatus1: NEW isactive1: False archived: False
但是请注意,通过这种安排,您已经失去了一些上下文:例如,您可以看到现在有两个相同的archived键,而在原始JSON中,它们是不同的,因为它们出现在层次结构的不同部分(installer.archivedvs. archived)。您将需要弄清楚如何自行处理该问题。
archived
installer.archived
小提琴:https : //dotnetfiddle.net/gzhWHk