C#如何遍历多层JSON提取特定键所有值并关联父级字段?
C# 多层嵌套JSON指定键值提取方案
问题核心需求
遍历任意深度嵌套的JSON结构,提取所有reading数组下的对象,同时拼接对应父节点的cid、cname字段,最终按指定格式输出。
原有代码核心问题
- 键名拼写错误:JSON结构中的嵌套子节点键为
childern,原代码误写为children,导致节点读取失败 - 递归逻辑错误:递归调用后未将子节点返回的
reading项合并到结果集,且递归时重复做JSON序列化/反序列化,是耗时过高的核心原因 - 字段映射错误:父节点字段读取错误(误读
id/name而非cid/cname),reading节点的id和name赋值颠倒 - 语法错误:
Jobject大小写错误应为JObject,Add方法参数使用错误的赋值符号,未将构造的对象加入结果数组
修正后可运行代码
需提前安装Nuget包 Newtonsoft.Json
using Newtonsoft.Json.Linq; using System.Collections.Generic; public class JsonProcessor { public string SensorList(string entireData) { if (string.IsNullOrEmpty(entireData)) return string.Empty; // 仅解析一次根JSON,避免重复解析开销 JObject root = JObject.Parse(entireData); JArray resultArray = new JArray(); // 递归遍历所有子节点,收集reading项 foreach (var child in root["childern"] ?? new JArray()) { var readingItems = TraverseChildern(child); foreach (var item in readingItems) { resultArray.Add(item); } } // 构造返回结果 JObject returnObj = new JObject(); returnObj.Add("name", root["name"]); returnObj.Add("id", root["id"]); returnObj.Add("value", resultArray); return returnObj.ToString(); } // 递归遍历子节点的辅助方法,直接操作JToken避免序列化开销 private IEnumerable<JObject> TraverseChildern(JToken node, string parentCid = null, string parentCname = null) { // 记录当前节点的cid、cname作为子节点的父级信息 string currentCid = node["cid"]?.ToString() ?? parentCid; string currentCname = node["cname"]?.ToString() ?? parentCname; // 处理当前节点的reading数组 if (node["reading"] is JArray readingArray) { foreach (var reading in readingArray) { JObject item = new JObject(); item.Add("id", reading["id"]); item.Add("name", reading["name"]); item.Add("cid", currentCid); item.Add("cname", currentCname); yield return item; } } // 递归处理子节点 if (node["childern"] is JArray childernArray) { foreach (var child in childernArray) { foreach (var childItem in TraverseChildern(child, currentCid, currentCname)) { yield return childItem; } } } } }
性能优化说明
- 全程仅做一次JSON解析,所有操作基于
JToken对象,避免递归过程中重复的序列化/反序列化开销,处理大体积JSON时性能提升显著 - 递归过程直接传递父级
cid、cname,无需回溯查找父节点,遍历效率更高 - 采用迭代器模式返回结果,减少不必要的中间数组拷贝,内存占用更低
内容的提问来源于stack exchange,提问作者june alex
相关产品推荐
相关产品推荐

