如何验证和删除 JSON 对象的嵌套节点
Posted
技术标签:
【中文标题】如何验证和删除 JSON 对象的嵌套节点【英文标题】:How to validate and remove nested nodes of JSON Object 【发布时间】:2019-12-31 17:48:12 【问题描述】:我有下面的 JSON 对象
"movieList":[
"movieID":1,
"title":"TITLE 1",
"showTimes":[
"date":"xx",
"time":["11:00" , "15:00" ]
,
"date":"xx",
"time":["11:00"]
,
"date":"xx",
"time":["18:00" ]
,
"date":"xx",
"time":["11:00" , "15:00" , "18:00" ]
]
]
想要删除“showTimes”数组下的以下节点。在这里,我试图删除“时间”属性中没有值“18:00”的节点。
"date":"xx",
"time":["11:00" , "15:00" ]
,
"date":"xx",
"time":["11:00"]
使用下面的代码,我可以在 foreach 循环中获取时间值
StreamReader rs = new StreamReader("xx.json");
string json = rs.ReadToEnd();
JObject jsonObject = JObject.Parse(json);
JToken jToken = JToken.Parse(json);
var result = jToken["movieList"].SelectMany(x => x["showTimes"].SelectMany(y => y["time"].Select(z => z)).ToList());
foreach (var item in result)
if (item.ToString() != "18:00")
// item.Parent.Remove();
如何在 foreach 循环中从我的 JSON 对象中删除上述节点?
【问题讨论】:
我建议从 app.quicktype.io?share=8CYNaPjpEs2AKwfL0F2x 开始。 我不能在这里使用模型类,想将动态 JSON 返回到 UI。 time("18:00" ) 是修改我的 JSON 对象的输入参数 为什么不能从具体类中生成所需的 JSON? 我知道这感觉就像我没有帮助 - 但如果人们使用具体的类作为他们的起点,95% 的 JSON 问题将会消失。 请参阅此link 可能会有所帮助。不过我强烈推荐你@mjwills 评论 Removing an element from a JSON response的可能重复 【参考方案1】:我也会建议使用模型类,但对于你的情况,这应该可以工作
JObject jsonObject = JObject.Parse(json);
JToken jToken = JToken.Parse(json);
var result = jToken["movieList"].SelectMany(x => x["showTimes"]).ToList();
foreach (var item in result)
var times = item.SelectTokens("time").Values().ToList();
if (!times.Where(x => x.ToString().Trim() == "18:00").Any())
item.Remove();
var output = jToken.ToString(Formatting.Indented);
Console.WriteLine(output);
输出
"movieList": [
"movieID": 1,
"title": "TITLE 1",
"showTimes": [
"date": "xx",
"time": [
"18:00"
]
,
"date": "xx",
"time": [
"11:00",
"15:00",
"18:00"
]
]
]
【讨论】:
【参考方案2】:您可以使用 Linq 及时查询不包含“18:00”的节点并删除它们。例如,
var jToken = JToken.Parse(json);
var result = jToken["movieList"].SelectMany(x=>x["showTimes"])
.Select(x=>x["time"])
.Where(x=>!x.Any(c=>c.Value<string>()=="18:00"))
.ToList();
foreach(var item in result)
item.Parent.Parent.Remove();
var output = jToken.ToString(Newtonsoft.Json.Formatting.Indented);
样本输出
"movieList": [
"movieID": 1,
"title": "TITLE 1",
"showTimes": [
"date": "xx",
"time": [
"18:00"
]
,
"date": "xx",
"time": [
"11:00",
"15:00",
"18:00"
]
]
]
【讨论】:
【参考方案3】:不要item.Parent.Remove()
,试试item.Remove()
:
var json = " \r\n \"movieList\":[ \r\n \r\n \"movieID\":1,\r\n \"title\":\"TITLE 1\",\r\n \"showTimes\":[ \r\n \r\n \"date\":\"xx\",\r\n \"time\":[\"11:00\" , \"15:00\" ]\r\n ,\r\n \r\n \"date\":\"xx\",\r\n \"time\":[\"11:00\"]\r\n ,\r\n \r\n \"date\":\"xx\",\r\n \"time\":[\"18:00\" ]\r\n ,\r\n \r\n \"date\":\"xx\",\r\n \"time\":[\"11:00\" , \"15:00\" , \"18:00\" ]\r\n \r\n ]\r\n \r\n ]\r\n";
var jToken = JToken.Parse(json);
var result = jToken["movieList"].SelectMany(x => x["showTimes"].SelectMany(y => y["time"].Select(z => z)).ToList());
foreach (var item in result)
if (item.ToString() != "18:00")
item.Remove();
var output = jToken.ToString(Formatting.Indented);
输出:
"movieList": [
"movieID": 1,
"title": "TITLE 1",
"showTimes": [
"date": "xx",
"time": []
,
"date": "xx",
"time": []
,
"date": "xx",
"time": [
"18:00"
]
,
"date": "xx",
"time": [
"18:00"
]
]
]
【讨论】:
你测试过这个吗?这看起来不像 OP 的要求 @ssilas777 是的,我确实测试过。它看起来不像 OP 的要求呢? 检查他想要的输出和你得到的输出 "date":"xx", "time":["18:00" ] , "date":"xx", "time":["11:00" , "15:00" , "18:00" ] .. 这应该是他的输出 @ssilas777 我把它读作 OP 想要删除不等于“18:00”的节点,这是他的代码示例正在尝试做的事情以上是关于如何验证和删除 JSON 对象的嵌套节点的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 express-validator 对嵌套对象进行验证