如何用ChoETL将复杂JSON转CSV?解决单行输出及字段控制问题
解决ChoETL嵌套JSON转多行无索引CSV并控制ExtraData字段的问题
核心配置要点
- 关闭数组索引后缀:设置
ArrayIndexMode = ChoArrayIndexMode.None - 展开嵌套数组为多行:启用
FlattenNode = true自动展开嵌套结构 - 动态控制字段:通过
IgnoreField方法根据开关决定是否保留ExtraData/ExtraData1
方案1:强类型实体类实现(结构固定场景)
1.1 定义对应实体类
public class RootObject { public int Id { get; set; } public string Name { get; set; } public List<Item> Items { get; set; } } public class Item { public int ItemId { get; set; } public string ItemName { get; set; } public string ExtraData { get; set; } public string ExtraData1 { get; set; } }
1.2 转换代码(支持字段开关)
using ChoETL; // 示例嵌套JSON string json = @" { ""Id"": 1, ""Name"": ""Test"", ""Items"": [ { ""ItemId"": 101, ""ItemName"": ""Item1"", ""ExtraData"": ""data1"", ""ExtraData1"": ""data1-1"" }, { ""ItemId"": 102, ""ItemName"": ""Item2"", ""ExtraData"": ""data2"", ""ExtraData1"": ""data2-1"" } ] }"; // 配置开关:是否包含ExtraData系列字段 bool includeExtraFields = true; using var reader = ChoJSONReader<RootObject>.LoadText(json) .Configure(c => { // 关闭默认的数组索引后缀(如Items[0].ItemId) c.ArrayIndexMode = ChoArrayIndexMode.None; // 展开嵌套数组为独立行 c.FlattenNode = true; }) // 根据开关动态忽略字段 .IgnoreField(!includeExtraFields, "ExtraData") .IgnoreField(!includeExtraFields, "ExtraData1"); using var writer = new ChoCSVWriter(Console.Out) .WithFirstLineHeader(); writer.Write(reader);
方案2:动态配置实现(结构不固定场景)
无需定义实体类,直接通过配置处理嵌套结构:
using ChoETL; string json = @" { ""Id"": 1, ""Name"": ""Test"", ""Items"": [ { ""ItemId"": 101, ""ItemName"": ""Item1"", ""ExtraData"": ""data1"", ""ExtraData1"": ""data1-1"" }, { ""ItemId"": 102, ""ItemName"": ""Item2"", ""ExtraData"": ""data2"", ""ExtraData1"": ""data2-1"" } ] }"; bool includeExtraFields = false; using var reader = ChoJSONReader.LoadText(json) .Configure(c => { c.ArrayIndexMode = ChoArrayIndexMode.None; c.FlattenNode = true; c.NestedKeySeparator = "."; }) .IgnoreField(!includeExtraFields, "Items.ExtraData") .IgnoreField(!includeExtraFields, "Items.ExtraData1"); using var writer = new ChoCSVWriter(Console.Out) .WithFirstLineHeader() // 移除字段名的嵌套前缀(如Items.ItemId转为ItemId) .Configure(c => c.FieldNameConverter = name => name.Replace("Items.", "")); writer.Write(reader);
关键配置说明
ArrayIndexMode = ChoArrayIndexMode.None:彻底消除默认生成的数组索引后缀,避免出现Items[0].ItemId这类字段名FlattenNode = true:将嵌套数组的每个元素转换为CSV的一行,解决原输出仅一行的问题IgnoreField(condition, fieldName):通过布尔开关动态控制字段是否保留,实现灵活配置FieldNameConverter:可选配置,用于移除嵌套字段的前缀,让CSV字段名更简洁
输出示例
当includeExtraFields=true时,输出CSV:
Id,Name,ItemId,ItemName,ExtraData,ExtraData1 1,Test,101,Item1,data1,data1-1 1,Test,102,Item2,data2,data2-1
当includeExtraFields=false时,输出将自动移除ExtraData和ExtraData1列。
内容的提问来源于stack exchange,提问作者Charline
相关产品推荐
相关产品推荐

