Cinchoo ETL——将复杂的嵌套JSON转换为CSV

目录

1、介绍

2. 要求

3. 使用方法

3.1 样本数据

3.2 快速转换

3.3 使用POCO对象

3.4 使用投影

3.5 使用选择


1、介绍

ChoETL是一个用于.NET的开源ETL(提取、转换和加载)框架。它是一个基于代码的库,用于在.NET环境中从多个来源提取数据、转换并加载到您自己的数据仓库中。您可以立即在数据仓库中拥有数据。

这个技巧讨论了使用Cinchoo ETL框架从JSON格式生成CSV文件。使用非常简单,只需几行代码,即可完成转换。您可以转换大文件,因为转换过程是基于流的、速度非常快且内存占用低。

2. 要求

该框架库是使用.NET 4.5/.NET Core FrameworksC#编写的。

3. 使用方法

3.1 样本数据

让我们首先看一个转换以下JSON输入文件的简单示例。

清单 3.1.1 示例JSON数据输入文件(Orders.json)

{
    "system": {
        "created": "2021-08-01T13:33:37.123Z",
        "by": "web"
    },
    "location": {
        "id": 100,
        "country": "DE"
    },
    "order": [
        {
            "OrderID": 22,
            "OrderName": "Soda",
            "OrderArticles": [
                {
                    "Size": 33,
                    "ProductName": "Coke",
                    "ProductId": "999"
                },
                {
                    "Size": 66,
                    "ProductName": "Fanta",
                    "ProductId": "888"
                },
                {
                    "Size": 50,
                    "ProductName": "Pepsi",
                    "ProductId": "444"
                }
            ],
            "ProcessedId": 1001,
            "Date": "2021-08-02"
        },
        {
            "OrderID": 23,
            "OrderName": "Beverage",
            "OrderArticles": [
                {
                    "Size": 44,
                    "ProductName": "Coke",
                    "ProductId": "999"
                }
            ],
            "ProcessedId": 1002,
            "Date": "2021-08-03"
        }
    ]
}

由于JSON消息是分层结构格式,因此您必须扁平化才能生成CSV文件。

假设您想生成以下CSV格式的输出。

清单 3.1.2 CSV数据输出文件(Orders.csv)

created;by;id;country;OrderID;OrderName;Size;ProductName;ProductId
2021-08-01T13:33:37.123Z;web;100;DE;22;Soda;33;Coke;999
2021-08-01T13:33:37.123Z;web;100;DE;22;Soda;66;Fanta;888
2021-08-01T13:33:37.123Z;web;100;DE;22;Soda;50;Pepsi;444
2021-08-01T13:33:37.123Z;web;100;DE;23;Beverage;44;Coke;999

首先要做的是安装ChoETL.JSON/ChoETL.JSON.NETStandard nuget包。为此,请在包管理器控制台中运行以下命令。

.NET Framework

Install-Package ChoETL.JSON

.NET Core

Install-Package ChoETL.JSON.NETStandard

现在ChoETL向程序添加命名空间。

using ChoETL;

3.2 快速转换

这种方法展示了如何用一小段代码将JSON文件转换为CSV格式。不需要设置/POCO类。

清单 3.2.1 快速JSONCSV文件转换

private static void QuickConversion()
{
    StringBuilder csv = new StringBuilder();
    using (var r = new ChoJSONReader("orders.json")
        .Configure(c => c.FlattenNode = true)
        .JsonSerializationSettings(s => s.DateParseHandling = DateParseHandling.None)
        )
    {
        using (var w = new ChoCSVWriter(csv)
            .WithDelimiter(";")
            .WithFirstLineHeader()
            .Configure(c => c.IgnoreDictionaryFieldPrefix = true)
            )
        {
            w.Write(r);
        }
    }
    Console.WriteLine(csv.ToString());
}

创建一个用于生成CSV ( orders.csv )文件的ChoCSVWriter实例。然后创建一个ChoJSONReader对象实例用于读取orders.json文件。这里通过使用JsonSerializationSettings(s => s.DateParseHandling = DateParseHandling.None)关闭datetime解析并将其作为文本处理。然后在CSV输出端,使用IgnoreDictionaryFieldPrefixtrue告诉CSV解析不要在输出中添加父节点前缀。

示例FiddleC# Online Compiler | .NET Fiddle

3.3 使用POCO对象

这种方法向您展示了如何定义POCO实体类并将它们用于转换过程。这种方法类型更安全,并且对转换过程进行了精细控制。使用json值填充对象后,使用LINQ为所需的CSV格式组合数据。

清单 3.3.1 映射类

public class System
{
    [JsonProperty("created")]
    public string Created { get; set; }

    [JsonProperty("by")]
    public string By { get; set; }
}

public class Location
{
    [JsonProperty("id")]
    public int Id { get; set; }

    [JsonProperty("country")]
    public string Country { get; set; }
}

public class OrderArticle
{
    [JsonProperty("Size")]
    public int Size { get; set; }

    [JsonProperty("ProductName")]
    public string ProductName { get; set; }

    [JsonProperty("ProductId")]
    public string ProductId { get; set; }
}

public class Order
{
    [JsonProperty("OrderID")]
    public int OrderID { get; set; }

    [JsonProperty("OrderName")]
    public string OrderName { get; set; }

    [JsonProperty("OrderArticles")]
    public List<OrderArticle> OrderArticles { get; set; }

    [JsonProperty("ProcessedId")]
    public int ProcessedId { get; set; }

    [JsonProperty("Date")]
    public string Date { get; set; }
}

public class OrderRoot
{
    [JsonProperty("system")]
    public System System { get; set; }

    [JsonProperty("location")]
    public Location Location { get; set; }

    [JsonProperty("order")]
    public List<Order> Orders { get; set; }
}

然后使用这个类如下进行文件的转换。

清单 3.3.2 使用POCO对象将JSON转换为CSV文件

private static void UsingPOCO()
{
    StringBuilder csv = new StringBuilder();
    using (var r = new ChoJSONReader<OrderRoot>("orders.json")
        .UseJsonSerialization()
        )
    {
        using (var w = new ChoCSVWriter(csv)
            .WithDelimiter(";")
            .WithFirstLineHeader())
        {
            w.Write(r.SelectMany(root =>
                root.Orders
                .SelectMany(order => order.OrderArticles
                .Select(orderarticle => new
                {
                    created = root.System.Created,
                    by = root.System.By,
                    id = root.Location.Id,
                    order.OrderID,
                    order.OrderName,
                    orderarticle.Size,
                    orderarticle.ProductName,
                    orderarticle.ProductId,
                })
                  )
                )
            );
        }
    }
    Console.WriteLine(csv.ToString());
}

Fiddle示例: C# Online Compiler | .NET Fiddle

3.4 使用投影

此方法展示了如何使用LINQ投影方法将JSON文件转换为CSV文件。您可能知道,JSON是一种分层的、关系的和结构化的数据,而CSV不是。如果您有从JSON读取器以分层格式生成的对象,则必须使用LINQ投影展平并将它们提供给CSV写入器以创建CSV文件。下面的示例显示了如何做到这一点。

清单 3.4.1 使用投影将JSON转换为CSV文件

private static void UsingProjection()
{
    StringBuilder csv = new StringBuilder();
    using (var r = new ChoJSONReader("orders.json")
        .JsonSerializationSettings(s => s.DateParseHandling = DateParseHandling.None)
        )
    {
        using (var w = new ChoCSVWriter(csv)
            .WithDelimiter(";")
            .WithFirstLineHeader())
        {
            w.Write(r.SelectMany(root =>
                ((Array)root.order).Cast<dynamic>()
                .SelectMany(order => ((Array)order.OrderArticles).Cast<dynamic>()
                .Select(orderarticle => new
                {
                    root.system.created,
                    root.system.by,
                    root.location.id,
                    order.OrderID,
                    order.OrderName,
                    orderarticle.Size,
                    orderarticle.ProductName,
                    orderarticle.ProductId,
                })
                    )
                )
            );
        }
    }
    Console.WriteLine(csv.ToString());
}

Fiddle示例:C# Online Compiler | .NET Fiddle

3.5 使用选择

该方法展示了如何使用选择方法结合展平节点将JSON文件转换为CSV文件。您可能知道,JSON是一种分层的、关系的和结构化的数据,而CSV不是。如果您有从JSON读取器以分层格式生成的对象,则必须使用FlattenNodetrue展平,然后选择所需的节点以生成输出。下面的示例显示了如何做到这一点。

清单 3.5.1 使用SelectionJSON转换为CSV文件

private static void UsingSelection()
{
    StringBuilder csv = new StringBuilder();
    using (var r = new ChoJSONReader("sample55.json")
        .WithField("created", jsonPath: "$..system.created", isArray: false)
        .WithField("by", jsonPath: "$..system.by", isArray: false)
        .WithField("id", jsonPath: "$..location.id", isArray: false)
        .WithField("country", jsonPath: "$..location.country", isArray: false)
        .WithField("OrderID")
        .WithField("OrderName")
        .WithField("Size")
        .WithField("ProductName")
        .WithField("ProductId")
        .Configure(c => c.FlattenNode = true)
        .JsonSerializationSettings(s => s.DateParseHandling = DateParseHandling.None)
        )
    {
        using (var w = new ChoCSVWriter(csv)
            .WithDelimiter(";")
            .WithFirstLineHeader())
        {
            w.Write(r);
        }
    }
    Console.WriteLine(csv.ToString());
}

Fiddle示例:C# Online Compiler | .NET Fiddle

https://www.codeproject.com/Tips/5312218/Cinchoo-ETL-Converting-Complex-Nested-JSON-to-CSV

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值