如何在SSIS中循环处理复杂JSON文件并反序列化为指定少量列
解决复杂JSON到Section/Component/Property/Value四列的批量转换问题
我太懂这种感觉了——把嵌套层级多的JSON转成规整的四列结构,比单纯拆字段要绕不少,尤其是还要批量处理多个文件。结合你用VS生成的RootObject类,咱们可以用递归遍历+层级追踪的思路来实现,下面给你具体的步骤和代码示例:
核心思路
因为你的JSON结构复杂,固定的字段映射肯定行不通,所以我们要:
- 递归遍历
RootObject及其嵌套类的所有属性 - 在遍历过程中,追踪当前节点对应的
Section、Component层级 - 遇到值类型属性时,将层级信息+属性名+值存入结果集合
具体实现步骤(C#示例)
1. 定义结果存储类
先建一个类来保存每一行的四列数据:
public class JsonTableResult { public string Section { get; set; } public string Component { get; set; } public string Property { get; set; } public string Value { get; set; } }
2. 编写递归遍历方法
这个方法会遍历对象的所有属性,递归处理嵌套类,同时记录当前的Section和Component:
using System.Reflection; public static List<JsonTableResult> MapJsonToTable(object obj, string currentSection = "", string currentComponent = "") { var results = new List<JsonTableResult>(); if (obj == null) return results; var properties = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (var prop in properties) { var propValue = prop.GetValue(obj); var propType = prop.PropertyType; // 判断是否是值类型或字符串(需要提取Value的节点) if (propType.IsValueType || propType == typeof(string)) { results.Add(new JsonTableResult { Section = currentSection, Component = currentComponent, Property = prop.Name, Value = propValue?.ToString() ?? string.Empty }); } // 如果是自定义类(嵌套的Component/Section),递归处理 else if (!propType.IsArray && !propType.IsGenericType) { // 这里可以根据你的结构调整Section/Component的层级逻辑 // 示例:假设当前属性是Section级,就更新currentSection;是Component级就更新currentComponent // 你可以根据实际JSON结构修改这个判断逻辑 string newSection = string.IsNullOrEmpty(currentSection) ? prop.Name : currentSection; string newComponent = propType.Name.Contains("Component") ? prop.Name : currentComponent; results.AddRange(MapJsonToTable(propValue, newSection, newComponent)); } // 处理数组或集合类型 else if (propType.IsGenericType && propType.GetGenericTypeDefinition() == typeof(List<>)) { var collection = propValue as IEnumerable; if (collection != null) { foreach (var item in collection) { results.AddRange(MapJsonToTable(item, currentSection, currentComponent)); } } } } return results; }
3. 批量处理JSON文件
读取多个JSON文件,反序列化为RootObject,然后调用上面的方法,最后可以把结果导出为CSV或DataTable:
using System.IO; using Newtonsoft.Json; // 或者用System.Text.Json public static void ProcessMultipleJsonFiles(string folderPath) { var allResults = new List<JsonTableResult>(); var jsonFiles = Directory.GetFiles(folderPath, "*.json"); foreach (var filePath in jsonFiles) { var jsonContent = File.ReadAllText(filePath); var rootObj = JsonConvert.DeserializeObject<RootObject>(jsonContent); // 调用映射方法,这里可以根据你的结构传入初始的Section名称(比如文件名) var fileResults = MapJsonToTable(rootObj, Path.GetFileNameWithoutExtension(filePath)); allResults.AddRange(fileResults); } // 示例:导出到CSV using (var writer = new StreamWriter("output.csv")) { writer.WriteLine("Section,Component,Property,Value"); foreach (var result in allResults) { writer.WriteLine($"{EscapeCsv(result.Section)},{EscapeCsv(result.Component)},{EscapeCsv(result.Property)},{EscapeCsv(result.Value)}"); } } } // CSV转义辅助方法 private static string EscapeCsv(string value) { if (value == null) return string.Empty; if (value.Contains(",") || value.Contains("\"") || value.Contains("\n")) { return $"\"{value.Replace("\"", "\"\"")}\""; } return value; }
关键调整点
你需要根据实际的RootObject结构,修改递归方法中的Section/Component层级判断逻辑:
- 比如如果某个嵌套类是Section的容器,就把它的属性名设为
currentSection - 如果某个类是Component,就把它的名称设为
currentComponent - 如果有更深的层级,还可以扩展逻辑(比如加SubComponent,但你的需求里是四列,所以控制好前两个层级就行)
这样处理后,不管JSON结构多复杂,都能把所有值类型的属性映射到对应的四列里,批量处理多个文件也不在话下。
内容的提问来源于stack exchange,提问作者AlanPear
相关产品推荐
相关产品推荐

