C# - 展平嵌套 Json

C# - Flatten Nested Json

我有多个具有不同布局的 JSON,我正在尝试创建一些代码来展平这些布局,然后将其转换为数据表。

例子JSON1

{
  "d": {
    "results": [
      {
        "__metadata": {
          "uri": "myuri.com",
          "type": "String"
        },
        "jobNumber": "123456789",
        "numberVacancy": "1",
        "some_obj": {
          "__metadata": {
            "uri": "myuri.com",
            "type": "String"
          },
          "code": "000012356"
        },
        "anothernested": {
          "results": [
            {
              "__metadata": {
                "uri": "myuri.com",
                "type": "String"
              },
              "picklistLabels": {
                "results": [
                  {
                    "__metadata": {
                      "uri": "myuri.com",
                      "type": "String"
                    },
                    "label": "Casual"
                  },
                  {
                    "__metadata": {
                      "uri": "myuri.com",
                      "type": "String"
                    },
                    "label": "Casual"
                  }
                ]
              }
            }
          ]
        }
      },
      {
        "__metadata": {
          "uri": "myuri.com",
          "type": "String"
        },
        "jobNumber": "987654321",
        "numberVacancy": "1",
        "some_obj": {
          "__metadata": {
            "uri": "myuri.com",
            "type": "String"
          },
          "code": "000012356"
        },
        "anothernested": {
          "results": [
            {
              "__metadata": {
                "uri": "myuri.com",
                "type": "String"
              },
              "picklistLabels": {
                "results": [
                  {
                    "__metadata": {
                      "uri": "myuri.com",
                      "type": "String"
                    },
                    "label": "Casual"
                  },
                  {
                    "__metadata": {
                      "uri": "myuri.com",
                      "type": "String"
                    },
                    "label": "Casual"
                  }
                ]
              }
            }
          ]
        }
      }
    ]
  }
}

我希望如何将 JSON 展平成数据表的示例。

__metadata/uri __metadata/类型 职位编号 人数空缺 some_obj/__metadata/uri some_obj/__metadata/type some_obj/code anothernested/results/0/__metadata/uri anothernested/results/0/__metadata/type anothernested/results/0/picklistLabels/results/0/__metadata/uri anothernested/results/0/picklistLabels/results/0/__metadata/type anothernested/results/0/picklistLabels/results/0/label anothernested/results/0/picklistLabels/results/1/__metadata/uri anothernested/results/0/picklistLabels/results/1/__metadata/type anothernested/results/0/picklistLabels/results/1/label
myuri.com 字符串 123456789 1 myuri.com 字符串 12356 myuri.com 字符串 myuri.com 字符串 休闲 myuri.com 字符串 休闲
myuri.com 字符串 987654321 1 myuri.com 字符串 12356 myuri.com 字符串 myuri.com 字符串 休闲 myuri.com 字符串 休闲

我将从 d.results 索引中拉平 JSON。

到目前为止,我已经将结果数组中每个单独的 Json 展平为字符串字典。但是,我不确定如何将其转换为数据表,请记住,有时字典中的元素可能顺序不同,或者每个 JSON 数组中的元素可能更多或更少。

IEnumerable<JToken> jTokens = jsonObject.Descendants().Where(p => p.Count() == 0);
results1 = jTokens.Aggregate(new Dictionary<string, string>(), (properties, jToken) =>
                    {
                        properties.Add(jToken.Path, jToken.ToString());
                        return properties;
                    });

要从您的源创建数据表json,您需要以下代码:

JObject jsonObject = JObject.Parse(json);
List<string> jpaths = jsonObject.Descendants().OfType<JProperty>().Where(jp => jp.Value is JArray).Select(jp => jp.Path).ToList();
List<JToken> rowtokens = jsonObject.SelectTokens("$.d.results.[*]").ToList();

DataTable resultTable = new DataTable();
resultTable.Columns.AddRange(((JObject)rowtokens[0]).Descendants().OfType<JProperty>().Where(jp => jp.Value is JValue).Select(jp => new DataColumn(jp.Path)).ToArray());
foreach (JToken rowtoken in rowtokens)
{
    resultTable.Rows.Add(((JObject)rowtoken).Descendants().OfType<JProperty>().Where(jp => jp.Value is JValue).Select(jp => jp.Value.ToString()).ToArray());
}
            

您可以尝试 Cinchoo ETL - 满足您需求的开源库。

using (var r = new ChoJSONReader("*** YOUR JSON FILE PATH ***")
    .WithJSONPath("$..d.results")
    .Configure(c => c.NestedColumnSeparator = '/')
    )
{
    var dt = r.AsDataTable();
    Console.WriteLine(dt.Dump());
}

输出:

__metadata/uri,__metadata/type,jobNumber,numberVacancy,some_obj/__metadata/uri,some_obj/__metadata/type,some_obj/code,anothernested/results/0/__metadata/uri,anothernested/results/0/__metadata/type,anothernested/results/0/picklistLabels/results/0/__metadata/uri,anothernested/results/0/picklistLabels/results/0/__metadata/type,anothernested/results/0/picklistLabels/results/0/label,anothernested/results/0/picklistLabels/results/1/__metadata/uri,anothernested/results/0/picklistLabels/results/1/__metadata/type,anothernested/results/0/picklistLabels/results/1/label
myuri.com,String,123456789,1,myuri.com,String,000012356,myuri.com,String,myuri.com,String,Casual,myuri.com,String,Casual
myuri.com,String,987654321,1,myuri.com,String,000012356,myuri.com,String,myuri.com,String,Casual,myuri.com,String,Casual

示例 fiddle:https://dotnetfiddle.net/DXBOYC

免责声明:我是这个库的作者。