C# - 展平嵌套的 Json
Posted
技术标签:
【中文标题】C# - 展平嵌套的 Json【英文标题】:C# - Flatten Nested 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;
);
【问题讨论】:
【参考方案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 并将每个对象分开。以上是关于C# - 展平嵌套的 Json的主要内容,如果未能解决你的问题,请参考以下文章