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
免责声明:我是这个库的作者。
我有多个具有不同布局的 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
免责声明:我是这个库的作者。