C#通过多个级别的数组仅基于键名查找JSON值

C#通过多个级别的数组仅基于键名查找JSON值,c#,json,linq,json.net,C#,Json,Linq,Json.net,我有各种输入JSON格式的数据,它们都包含一个特定的键名terminalSize。这是我所知道的唯一一件。JSON树的总数或JSON树中terminalSize的确切深度将永远是未知的,并且可能会发生变化 我正在寻找一个C#解决方案,循环遍历JSON字符串的每个子元素,找到terminalSize,然后获取值 我已经成功地尝试了这一点,但只有当terminalSize处于JSON的第一级时,它才会起作用: var list = JsonConvert.DeserializeObject<L

我有各种输入JSON格式的数据,它们都包含一个特定的键名
terminalSize
。这是我所知道的唯一一件。JSON树的总数或JSON树中
terminalSize
的确切深度将永远是未知的,并且可能会发生变化

我正在寻找一个C#解决方案,循环遍历JSON字符串的每个子元素,找到
terminalSize
,然后获取值

我已经成功地尝试了这一点,但只有当
terminalSize
处于JSON的第一级时,它才会起作用:

var list = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(jsonString);
var dict = list.SelectMany(d => d).ToDictionary(p => p.Key, p => p.Value);
var terminal = dict["terminalSize"];
var terminalSize = (double?) JToken.Parse(json).SelectToken("$..terminalSize");
例2

{
  "lastUpdated": 1588020678,
  "terminalData": {
    "terminalSize": "451679852",
    "totalTerminalSize": "2100000000"
  },
  "terminalValueSeries": {
    "8x7": 2.33,
    "8x6": 3.73,
    "8x5": 4.49,
    "8x4": 3.68,
    "8x3": 13998,
    "8x2": 274936,
    "8x1": 5.09
  }
}
例3

{
  "terminalSize": "492612346.17",
  "terminalStatus": "online"
}

您可以将JSON解析为,然后递归地遍历所有属性和子对象,以找到
ternalSize
值。无需将整个JSON反序列化为特定对象

var json=JObject.Parse(jsonString); var result=GetTerminalSize(json); 双GetTerminalSize(作业对象输入) { foreach(input.Properties()中的var属性) { 如果(property.Name==“terminalSize”) 返回property.Value.Value(); if(property.Value.Type==JTokenType.Object) 返回GetTerminalSize((JObject)property.Value); //不确定是否需要处理数组 if(property.Value.Type==JTokenType.Array) foreach(JArray属性.Value中的变量项) 返回GetTerminalSize((JObject)项); } 返回0; }
它为所有3个示例返回一个正确的值

您可以将JSON解析为,然后与递归下降运算符
一起使用。
获取JSON中任意位置的
terminalSize

var list = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(jsonString);
var dict = list.SelectMany(d => d).ToDictionary(p => p.Key, p => p.Value);
var terminal = dict["terminalSize"];
var terminalSize = (double?) JToken.Parse(json).SelectToken("$..terminalSize");
小提琴:

如果JSON中可能有多个
terminalSize
键,例如,如果您有一个终端数组,您可以使用
SelectTokens
,将终端大小放入一个
字典中,并按路径设置键:

var sizes = JToken.Parse(json4)
                  .SelectTokens("$..terminalSize")
                  .ToDictionary(t => t.Path, t => (double)t);

Fiddle:

您还可以使用linq并基于
JProperty.Name
过滤
JProperty
集合。比如说

var result = JObject.Parse(jsonString)
                    .DescendantsAndSelf()
                    .OfType<JProperty>()
                    .Single(x=>x.Name.Equals("terminalSize"))
                    .Value;
var result=JObject.Parse(jsonString)
.后代和自我()
第()类
.Single(x=>x.Name.Equals(“terminalSize”))
价值

终端尺寸是否仅显示一次?感谢您提供的小提琴链接和示例。非常有帮助!谢谢,非常有帮助