【问题标题】:Convert and parse json string to key value pairs using NewtonSoft使用 NewtonSoft 将 json 字符串转换并解析为键值对
【发布时间】:2020-05-28 13:07:37
【问题描述】:

尝试使用 Newtonsoft 将 json 字符串转换为键值对,但目前没有运气。

来自 API 的响应:

var response = @"{'result':{'0199 - B344EE33':
{
     '6400_00260100':{'1':[{'val':336688}]},
     '6400_00462500':{'1':[{'val':null}]},
     '6800_00832A00':{'1':[{'low':3000,'high':3000,'val':3000}]},
     '6800_008AA200':{'1':[{'low':0,'high':null,'val':0}]}
}}}";

我想要的结果是一个新的键值对对象:

{
    "6400_00260100" : 336688,
    "6400_00462500" : null,
    "6800_00832A00" : 3000,
    "6800_008AA200" : 0
}

在响应中,result 将始终是第一个也是唯一的道具。在下一个级别中,代码0199 - B344EE33 可以更改,但在此级别中只有一个道具,所以我们总是可以拿第一个。然后在最后一层我们总是需要val 属性。

我所拥有的是以下内容,但为了以干净的方式获取键值对,我陷入了困境:

var json = JObject.Parse(response);
var result = json["result"].First;
var path = result.Path;

更新

        var jObjectResult = new JObject();

        var response = @"{'result':{'0199 - B344EE33':
                        {
                            '6800_10821E00':{'1':[{'val':'SMA Sunny Boy'}]},
                            '6800_00A21E00':{'1':[{'val':'3.0.0.2222'}]},
                            '6800_00823400':{'1':[{'low':3000,'high':3000,'val':3000}]},
                            '6800_08822B00':{'1':[{'val':'SMA'}]},
                            '6800_08822000':{'1':[{'val':'Sunny Boy 3.0'}]}
                        }}}";

        var json = JObject.Parse(response);
        var json_serial = json["result"].First.Children<JObject>().ToList()[0];

        foreach(var token in json_serial)
        {
            var tokenKey = token.Key;
            var tokenVal = token.Value.SelectToken("$.1[0].val");

            jObjectResult.Add(tokenKey, tokenVal);
        }

【问题讨论】:

  • 您的 JSON 示例看起来有多层嵌套。您可能最好先尝试将其放入 c# 类对象,然后将您需要的位投影到字典中。
  • @t.karalis 我为什么要这样做?我只需要将其中的 key 和 val 值放入字典或列表或其他任何内容中。创建嵌套对象来实现这一点似乎有点过头了。
  • 只是从不同的角度来看,如果有一种方法可以反序列化它而不必手动解析 json,那么这对我来说似乎更简单;) 诚然,我还没有想出还有什么。
  • 有一些工作,请参阅我的问题中的更新,但也许可以简单化。
  • 太好了,我唯一要避免的是不必要地致电.ToList()。我将 .ToList()[0] 替换为 .First().FirstOrDefault()

标签: json asp.net-core json.net


【解决方案1】:

您可以使用SelectTokens 和递归下降运算符.. 来查找所有val 属性,然后重复使用.Parent 遍历链以获取相应的键。从此信息创建新的JProperties 并将它们放入新的JObject 以获得您的结果。这是一个“单行”:

var result = new JObject(
    JObject.Parse(response)
           .SelectTokens("$..val")
           .Select(jt => new JProperty(
               ((JProperty)jt.Parent.Parent.Parent.Parent.Parent.Parent).Name,
               jt
           ))
);

小提琴:https://dotnetfiddle.net/TbZ7LS

【讨论】:

    【解决方案2】:

    最后,@Brian Rogers 给出了一些指针,我提出了以下解决方案:

        // Arrange
        var response = @"{'result':{'0199 - B344EE33':
                        {
                            '6800_10821E00':{'1':[{'val':'SMA Sunny Boy'}]},
                            '6800_00A21E00':{'1':[{'val':'3.0.0.2222'}]},
                            '6800_00823400':{'1':[{'low':3000,'high':3000,'val':3000}]},
                            '6800_08822B00':{'1':[{'val':'SMA'}]},
                            '6800_08822000':{'1':[{'val':'Sunny Boy 3.0'}]}
                        }}}";
    
        // Act
        var json = JObject.Parse(response);
        var json_serial = (JProperty)json["result"].First();
        var jObjectResult = new JObject(
            json_serial.Value.Select(p =>
            {
                return new JProperty(
                    ((JProperty)p).Name,
                    p.First.SelectToken("$.1[0].val")
                );
            }));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2018-08-12
      • 2017-08-03
      • 2015-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多