【问题标题】:How to validate and remove nested nodes of JSON Object如何验证和删除 JSON 对象的嵌套节点
【发布时间】: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 对象中删除上述节点?

【问题讨论】:

  • 我不能在这里使用模型类,想将动态 JSON 返回到 UI。 time("18:00" ) 是修改我的 JSON 对象的输入参数
  • 为什么不能从具体类中生成所需的 JSON? 我知道这感觉就像我没有帮助 - 但如果人们使用具体的类作为他们的起点,95% 的 JSON 问题将会消失。
  • 请参阅此link 可能会有所帮助。不过我强烈推荐你@mjwills 评论

标签: c# json asp.net-web-api json.net


【解决方案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”的节点,这是他的代码示例正在尝试做的事情
      猜你喜欢
      • 2021-08-21
      • 2023-01-31
      • 2017-08-21
      • 2019-01-25
      • 2020-07-28
      • 1970-01-01
      • 2021-10-19
      • 2021-04-12
      相关资源
      最近更新 更多