【问题标题】:C# - Flatten Nested JsonC# - 展平嵌套的 Json
【发布时间】:2021-09-05 02:37:03
【问题描述】:

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

示例 JSON 1

{
  "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/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 12356 myuri.com String myuri.com String Casual myuri.com String Casual
myuri.com String 987654321 1 myuri.com String 12356 myuri.com String myuri.com String Casual myuri.com String Casual

我将从 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;
                    });

【问题讨论】:

    标签: c# arrays json json.net flatten


    【解决方案1】:

    您可以尝试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
    

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

    【讨论】:

      【解决方案2】:

      要从源 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());
      }
                  
      

      【讨论】:

      • 谢谢你,这很好用。展平整个 JSON 并将每个对象分开。
      猜你喜欢
      • 2016-10-06
      • 1970-01-01
      • 2021-07-14
      • 2021-10-19
      • 2012-05-29
      • 2014-08-29
      • 2020-03-08
      • 2020-03-02
      相关资源
      最近更新 更多