解析含多对象的动态JSON遇JObject.Parse异常,如何提取所有name属性?
解决JSON数组解析异常并提取所有name属性值
这个问题我碰到过不少次,核心原因是你用错了解析方法——JObject.Parse()是用来解析单个JSON对象的,但你的输入是被[]包裹的JSON数组(多个对象的集合),所以才会抛出「存在额外文本」的异常。下面给你一套完整的解决方案,还会兼顾你提到的“可能是单个对象/数组、children可能为空或嵌套”的动态结构情况。
第一步:替换解析方法
把JObject.Parse()换成JArray.Parse(),就能正确解析数组格式的JSON。如果你的JSON有时候是单个对象(没有[]包裹),可以加个容错判断,自动把单个对象包装成数组,兼容两种场景。
第二步:递归遍历嵌套结构收集name值
因为children属性是动态嵌套的,我们需要写一个递归方法,遍历所有层级的节点,提取每个节点的name值。
完整代码示例
using Newtonsoft.Json.Linq; using System.Collections.Generic; using System; public class JsonProcessor { public static List<string> ExtractAllNames(string jsonInput) { List<string> allNames = new List<string>(); JToken rootNode; // 兼容单个对象和数组两种情况 try { rootNode = JArray.Parse(jsonInput); } catch (Exception) { // 解析数组失败,尝试解析单个对象并包装成数组 rootNode = new JArray(JObject.Parse(jsonInput)); } // 遍历根节点下的所有元素,递归收集name foreach (JToken node in rootNode) { TraverseNode(node, allNames); } return allNames; } private static void TraverseNode(JToken currentNode, List<string> nameList) { // 提取当前节点的name属性,避免空引用 string currentName = currentNode["name"]?.ToString(); if (!string.IsNullOrWhiteSpace(currentName)) { nameList.Add(currentName); } // 处理children节点:如果存在且不为空数组,继续递归遍历 JArray children = currentNode["children"] as JArray; if (children != null && children.Count > 0) { foreach (JToken childNode in children) { TraverseNode(childNode, nameList); } } } }
使用示例
// 你的示例JSON string sampleJson = @"[ { ""name"": ""AML Policy"", ""children"": [ { ""name"": ""Test"", ""children"": [ { ""name"": ""Test123"", ""children"": [] } ] } ] }, { ""name"": ""AML Policy2"", ""children"": [] } ]"; // 提取所有name值 List<string> names = JsonProcessor.ExtractAllNames(sampleJson); // 输出结果:AML Policy、Test、Test123、AML Policy2 foreach (string name in names) { Console.WriteLine(name); }
关键说明
- 容错处理:通过try-catch兼容单个对象和数组两种输入格式,不用额外判断JSON的开头字符。
- 递归遍历:不管
children嵌套多少层,都能逐层提取name值,空数组会被自动忽略。 - 空值安全:使用
?.ToString()避免name属性不存在时抛出空引用异常。
内容的提问来源于stack exchange,提问作者Neelam
相关产品推荐
相关产品推荐

