嵌套JSON中提取所有sensors的Name和Frequency字段问题排查
解决嵌套JSON中提取所有sensors下Name和Frequency的问题
嘿,我来帮你搞定这个嵌套JSON的字段提取问题~你的代码之所以卡住或者拿不到目标字段,是因为循环层级和JSON节点的访问方式没对应上,咱们一步步来修正。
问题根源分析
你用$..sensors拿到的是所有层级下的sensors节点,每个sensors节点是一个JObject,里面的键是传感器的ID(比如2523532523),而每个键对应的值才是包含Name和Frequency的对象。原代码的循环没有正确定位到这个值对象,导致无法获取目标字段。
方案一:直接定位到所有传感器对象
用$..sensors.*的JSONPath表达式,直接拿到所有sensors节点下的子对象(也就是每个具体的传感器项),跳过中间的传感器ID层级,直接访问目标字段:
var p = "{ \"info\":{ \"23423424234\":{ \"id\":\"23423424234\", \"sensors\":{ \"2523532523\":{ \"Name\":\"test\", \"Frequency\":\"1\" }, \"46546456456\":{ \"Name\":\"test1\", \"Frequency\":\"5\" } } } }, \"vol\":{ \"568768678678\":{ \"id\":\"568768678678\", \"sensors\":{ \"67867867867\":{ \"Name\":\"test1\", \"Frequency\":\"1\" }, \"65474574754\":{ \"Name\":\"test8\", \"Frequency\":\"5\" } } } } }"; // 解析JSON var jsonToken = JToken.Parse(p); // 用JSONPath直接定位所有sensors下的传感器对象 var allSensors = jsonToken.SelectTokens("$..sensors.*").ToList(); // 遍历每个传感器对象,提取字段 foreach (var sensor in allSensors) { string name = sensor["Name"]?.ToString() ?? "N/A"; string frequency = sensor["Frequency"]?.ToString() ?? "N/A"; Console.WriteLine($"Name: {name}, Frequency: {frequency}"); }
方案二:逐层遍历节点(更清晰展示层级关系)
如果你想保留逐层遍历的逻辑,需要调整循环,先遍历sensors节点的属性(传感器ID),再访问属性的值对象来获取字段:
var p = "{ \"info\":{ \"23423424234\":{ \"id\":\"23423424234\", \"sensors\":{ \"2523532523\":{ \"Name\":\"test\", \"Frequency\":\"1\" }, \"46546456456\":{ \"Name\":\"test1\", \"Frequency\":\"5\" } } } }, \"vol\":{ \"568768678678\":{ \"id\":\"568768678678\", \"sensors\":{ \"67867867867\":{ \"Name\":\"test1\", \"Frequency\":\"1\" }, \"65474574754\":{ \"Name\":\"test8\", \"Frequency\":\"5\" } } } } }"; var jsonToken = JToken.Parse(p); // 获取所有层级的sensors节点 var sensorsNodes = jsonToken.SelectTokens("$..sensors").ToList(); foreach (var sensorsNode in sensorsNodes) { // 遍历sensors节点下的每个传感器ID属性 foreach (JProperty sensorProp in sensorsNode.Properties()) { // sensorProp.Value 就是包含Name和Frequency的对象 var sensorObj = sensorProp.Value; string name = sensorObj["Name"]?.ToString() ?? "N/A"; string frequency = sensorObj["Frequency"]?.ToString() ?? "N/A"; Console.WriteLine($"Name: {name}, Frequency: {frequency}"); } }
原代码卡住的原因
原代码中,foreach(var ty in tt)遍历的是sensors节点的属性(比如2523532523),ty是JProperty类型,而你接着用foreach (JProperty prop in ty.Properties())去遍历它的属性,这就错了——ty的Value才是真正的传感器对象,你应该访问ty.Value来获取Name和Frequency,而不是遍历它的属性。
内容的提问来源于stack exchange,提问作者vct




