使用C#从现有JSON文件提取属性生成新JSON文件
动态提取指定JSON属性并生成新文件
实现思路
用动态JSON处理库(Newtonsoft.Json 或 System.Text.Json)来操作无固定模型的JSON结构,通过定义提取规则筛选目标主属性及子属性,最后序列化保存为新文件,全程无需硬编码数据模型。
具体实现方案
方案一:用Newtonsoft.Json(Json.NET)实现
既然你已经在使用JObject,这个方案更贴合你的现有操作,处理动态结构也更灵活:
using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; class JsonExtractor { static void Main() { // 定义动态提取规则:键是主属性名,值是要保留的子属性列表 var extractRules = new Dictionary<string, List<string>> { { "Two", new List<string> { "SomeProp2", "SomeProp3" } }, { "Three", new List<string> { "SomeProp3" } } }; // 读取原始JSON文件 string originalPath = "original.json"; JObject originalObj = JObject.Parse(File.ReadAllText(originalPath)); // 构建新的JSON对象 JObject newJsonObj = new JObject(); foreach (var rule in extractRules) { string mainPropName = rule.Key; // 检查原始JSON是否存在该主属性 if (originalObj.TryGetValue(mainPropName, out JToken mainPropToken)) { if (mainPropToken.Type == JTokenType.Object) { // 筛选子属性 JObject filteredSubObj = new JObject(); foreach (string subProp in rule.Value) { if (mainPropToken[subProp] != null) { // 深拷贝保留原始类型 filteredSubObj[subProp] = mainPropToken[subProp].DeepClone(); } } newJsonObj[mainPropName] = filteredSubObj; } else { // 主属性不是对象类型(如字符串、数字),直接保留 newJsonObj[mainPropName] = mainPropToken.DeepClone(); } } } // 保存新JSON文件 string newPath = "filtered.json"; File.WriteAllText(newPath, newJsonObj.ToString(Formatting.Indented)); } }
方案二:用System.Text.Json实现
如果必须用官方的System.Text.Json,可通过JsonDocument动态处理:
using System; using System.Collections.Generic; using System.IO; using System.Text.Json; class JsonExtractor { static void Main() { var extractRules = new Dictionary<string, List<string>> { { "Two", new List<string> { "SomeProp2", "SomeProp3" } }, { "Three", new List<string> { "SomeProp3" } } }; string originalPath = "original.json"; using JsonDocument doc = JsonDocument.Parse(File.ReadAllText(originalPath)); JsonElement root = doc.RootElement; // 写入新JSON using var stream = new MemoryStream(); using var writer = new Utf8JsonWriter(stream, new JsonWriterOptions { Indented = true }); writer.WriteStartObject(); foreach (var rule in extractRules) { string mainProp = rule.Key; if (root.TryGetProperty(mainProp, out JsonElement mainElement)) { writer.WritePropertyName(mainProp); if (mainElement.ValueKind == JsonValueKind.Object) { writer.WriteStartObject(); foreach (string subProp in rule.Value) { if (mainElement.TryGetProperty(subProp, out JsonElement subElement)) { // 直接写入保留原始类型 subElement.WriteTo(writer); } } writer.WriteEndObject(); } else { mainElement.WriteTo(writer); } } } writer.WriteEndObject(); writer.Flush(); // 保存到文件 string newJson = System.Text.Encoding.UTF8.GetString(stream.ToArray()); File.WriteAllText("filtered.json", newJson); } }
关键注意点
- 用深拷贝(Newtonsoft)或直接写入元素(System.Text.Json)的方式,确保原始值的类型(如数字、布尔值)不会丢失
- 提取规则用字典存储,后续要调整提取的属性,只需修改字典内容,无需改动核心代码
- 加入了非对象类型主属性的处理逻辑,覆盖更多场景
内容的提问来源于stack exchange,提问作者Superfreak3
相关产品推荐
相关产品推荐

