简体   繁体   English

将具有多个嵌套数组的通用 Json 转换为数据表 C#

[英]Convert generic Json with multiple nested array to a Datatable C#

I need help, I need a function that recive a Json and returns a Datatable, any input can come in Json format so I can't use a object. I need help, I need a function that recive a Json and returns a Datatable, any input can come in Json format so I can't use a object. My problem is when the Json comes with multiple Arrays nested in the response (the Json can have any format, it can come without Arrays or it can come with 1 or more Arrays), any idea how to make this possible? My problem is when the Json comes with multiple Arrays nested in the response (the Json can have any format, it can come without Arrays or it can come with 1 or more Arrays), any idea how to make this possible? I need the algorithm to be as generic as possible.我需要算法尽可能通用。 Thanks谢谢

I leave an example input and what I expect to get我留下一个示例输入和我期望得到的

        public const string ResponseThreeArrays = @"{
        ""key1"": ""val1"",
        ""key2"": {
            ""key2-1"": 
            [
                {
                    ""key2-arr1-1"": ""val2-arr1-1(1)"",
                    ""key2-arr1-2"": 
                    [
                        {
                            ""key2-arr1-arr2-1"" : ""val2-arr1-arr2-1(1)(1)"",
                            ""key2-arr1-arr2-2"" : 
                            [
                                {
                                    ""key2-arr1-arr2-arr3-1"" : ""val2-arr1-arr2-arr3-1(1)(1)(1)"",
                                    ""key2-arr1-arr2-arr3-2"" : ""val2-arr1-arr2-arr3-2(1)(1)(1)"",
                                    ""key2-arr1-arr2-arr3-3"" : ""val2-arr1-arr2-arr3-3(1)(1)(1)""
                                },
                                {
                                    ""key2-arr1-arr2-arr3-1"" : ""val2-arr1-arr2-arr3-1(1)(1)(2)"",
                                    ""key2-arr1-arr2-arr3-2"" : ""val2-arr1-arr2-arr3-2(1)(1)(2)"",
                                    ""key2-arr1-arr2-arr3-3"" : ""val2-arr1-arr2-arr3-3(1)(1)(2)""
                                },
                                {
                                    ""key2-arr1-arr2-arr3-1"" : ""val2-arr1-arr2-arr3-1(1)(1)(3)"",
                                    ""key2-arr1-arr2-arr3-2"" : ""val2-arr1-arr2-arr3-2(1)(1)(3)"",
                                    ""key2-arr1-arr2-arr3-3"" : ""val2-arr1-arr2-arr3-3(1)(1)(3)""
                                }
                            ],
                            ""key2-arr1-arr2-3"" : ""val2-arr1-arr2-3(1)(1)""
                        },
                        {
                            ""key2-arr1-arr2-1"" : ""val2-arr1-arr2-1(1)(2)"",
                            ""key2-arr1-arr2-2"" : 
                            [
                                {
                                    ""key2-arr1-arr2-arr3-1"" : ""val2-arr1-arr2-arr3-1(1)(2)(1)"",
                                    ""key2-arr1-arr2-arr3-2"" : ""val2-arr1-arr2-arr3-2(1)(2)(1)"",
                                    ""key2-arr1-arr2-arr3-3"" : ""val2-arr1-arr2-arr3-3(1)(2)(1)""
                                },
                                {
                                    ""key2-arr1-arr2-arr3-1"" : ""val2-arr1-arr2-arr3-1(1)(2)(2)"",
                                    ""key2-arr1-arr2-arr3-2"" : ""val2-arr1-arr2-arr3-2(1)(2)(2)"",
                                    ""key2-arr1-arr2-arr3-3"" : ""val2-arr1-arr2-arr3-3(1)(2)(2)""
                                },
                                {
                                    ""key2-arr1-arr2-arr3-1"" : ""val2-arr1-arr2-arr3-1(1)(2)(3)"",
                                    ""key2-arr1-arr2-arr3-2"" : ""val2-arr1-arr2-arr3-2(1)(2)(3)"",
                                    ""key2-arr1-arr2-arr3-3"" : ""val2-arr1-arr2-arr3-3(1)(2)(3)""
                                }
                            ],
                            ""key2-arr1-arr2-3"" : ""val2-arr1-arr2-3(1)(2)""
                        }
                    ]
                },
                {
                    ""key2-arr1-1"": ""val2-arr1-1(2)"",
                    ""key2-arr1-2"": 
                    [
                        {
                            ""key2-arr1-arr2-1"" : ""val2-arr1-arr2-1(2)(1)"",
                            ""key2-arr1-arr2-2"" : 
                            [
                                {
                                    ""key2-arr1-arr2-arr3-1"" : ""val2-arr1-arr2-arr3-1(2)(1)(1)"",
                                    ""key2-arr1-arr2-arr3-2"" : ""val2-arr1-arr2-arr3-2(2)(1)(1)"",
                                    ""key2-arr1-arr2-arr3-3"" : ""val2-arr1-arr2-arr3-3(2)(1)(1)""
                                },
                                {
                                    ""key2-arr1-arr2-arr3-1"" : ""val2-arr1-arr2-arr3-1(2)(1)(2)"",
                                    ""key2-arr1-arr2-arr3-2"" : ""val2-arr1-arr2-arr3-2(2)(1)(2)"",
                                    ""key2-arr1-arr2-arr3-3"" : ""val2-arr1-arr2-arr3-3(2)(1)(2)""
                                 },
                                 {
                                    ""key2-arr1-arr2-arr3-1"" : ""val2-arr1-arr2-arr3-1(2)(1)(3)"",
                                    ""key2-arr1-arr2-arr3-2"" : ""val2-arr1-arr2-arr3-2(2)(1)(3)"",
                                    ""key2-arr1-arr2-arr3-3"" : ""val2-arr1-arr2-arr3-3(2)(1)(3)""
                                 }
                            ],
                            ""key2-arr1-arr2-3"" : ""val2-arr1-arr2-3(2)(1)""
                        },
                        {
                            ""key2-arr1-arr2-1"" : ""val2-arr1-arr2-1(2)(2)"",
                            ""key2-arr1-arr2-2"" : 
                            [
                                {
                                    ""key2-arr1-arr2-arr3-1"" : ""val2-arr1-arr2-arr3-1(2)(2)(1)"",
                                    ""key2-arr1-arr2-arr3-2"" : ""val2-arr1-arr2-arr3-2(2)(2)(1)"",
                                    ""key2-arr1-arr2-arr3-3"" : ""val2-arr1-arr2-arr3-3(2)(2)(1)""
                                },
                                {
                                    ""key2-arr1-arr2-arr3-1"" : ""val2-arr1-arr2-arr3-1(2)(2)(2)"",
                                    ""key2-arr1-arr2-arr3-2"" : ""val2-arr1-arr2-arr3-2(2)(2)(2)"",
                                    ""key2-arr1-arr2-arr3-3"" : ""val2-arr1-arr2-arr3-3(2)(2)(2)""
                                },
                                {
                                    ""key2-arr1-arr2-arr3-1"" : ""val2-arr1-arr2-arr3-1(2)(2)(3)"",
                                    ""key2-arr1-arr2-arr3-2"" : ""val2-arr1-arr2-arr3-2(2)(2)(3)"",
                                    ""key2-arr1-arr2-arr3-3"" : ""val2-arr1-arr2-arr3-3(2)(2)(3)""
                                }
                            ],
                           ""key2-arr1-arr2-3"" : ""val2-arr1-arr2-3(2)(2)""
                        }
                    ]
                }
            ],
            ""key2-2"" : ""val2-2""
            },
        ""key3"": ""val3""
        }";

And this is what I expect obtain:这就是我期望得到的:

Datatable expected预期数据表

Use Cinchoo ETL - an open source library to do such conversion easily.使用Cinchoo ETL - 一个开源库来轻松进行这种转换。 (Not sure, this meets your requirement) (不确定,这符合您的要求)

using (var r = ChoJSONReader.LoadText(ResponseThreeArrays)
       .ErrorMode(ChoErrorMode.IgnoreAndContinue)
      )
{
    var dt = r.FlattenBy("key2", "key2-1", "key2-arr1-2", "key2-arr1-arr2-2").AsDataTable();
    dt.Print();
}

Output: Output:

key1,key3,key2-2,key2-arr1-1,key2-arr1-arr2-1,key2-arr1-arr2-3,key2-arr1-arr2-arr3-1,key2-arr1-arr2-arr3-2,key2-arr1-arr2-arr3-3
val1,val3,val2-2,val2-arr1-1(1),val2-arr1-arr2-1(1)(1),val2-arr1-arr2-3(1)(1),val2-arr1-arr2-arr3-1(1)(1)(1),val2-arr1-arr2-arr3-2(1)(1)(1),val2-arr1-arr2-arr3-3(1)(1)(1)
val1,val3,val2-2,val2-arr1-1(1),val2-arr1-arr2-1(1)(1),val2-arr1-arr2-3(1)(1),val2-arr1-arr2-arr3-1(1)(1)(2),val2-arr1-arr2-arr3-2(1)(1)(2),val2-arr1-arr2-arr3-3(1)(1)(2)
val1,val3,val2-2,val2-arr1-1(1),val2-arr1-arr2-1(1)(1),val2-arr1-arr2-3(1)(1),val2-arr1-arr2-arr3-1(1)(1)(3),val2-arr1-arr2-arr3-2(1)(1)(3),val2-arr1-arr2-arr3-3(1)(1)(3)
val1,val3,val2-2,val2-arr1-1(1),val2-arr1-arr2-1(1)(2),val2-arr1-arr2-3(1)(2),val2-arr1-arr2-arr3-1(1)(2)(1),val2-arr1-arr2-arr3-2(1)(2)(1),val2-arr1-arr2-arr3-3(1)(2)(1)
val1,val3,val2-2,val2-arr1-1(1),val2-arr1-arr2-1(1)(2),val2-arr1-arr2-3(1)(2),val2-arr1-arr2-arr3-1(1)(2)(2),val2-arr1-arr2-arr3-2(1)(2)(2),val2-arr1-arr2-arr3-3(1)(2)(2)
val1,val3,val2-2,val2-arr1-1(1),val2-arr1-arr2-1(1)(2),val2-arr1-arr2-3(1)(2),val2-arr1-arr2-arr3-1(1)(2)(3),val2-arr1-arr2-arr3-2(1)(2)(3),val2-arr1-arr2-arr3-3(1)(2)(3)
val1,val3,val2-2,val2-arr1-1(2),val2-arr1-arr2-1(2)(1),val2-arr1-arr2-3(2)(1),val2-arr1-arr2-arr3-1(2)(1)(1),val2-arr1-arr2-arr3-2(2)(1)(1),val2-arr1-arr2-arr3-3(2)(1)(1)
val1,val3,val2-2,val2-arr1-1(2),val2-arr1-arr2-1(2)(1),val2-arr1-arr2-3(2)(1),val2-arr1-arr2-arr3-1(2)(1)(2),val2-arr1-arr2-arr3-2(2)(1)(2),val2-arr1-arr2-arr3-3(2)(1)(2)
val1,val3,val2-2,val2-arr1-1(2),val2-arr1-arr2-1(2)(1),val2-arr1-arr2-3(2)(1),val2-arr1-arr2-arr3-1(2)(1)(3),val2-arr1-arr2-arr3-2(2)(1)(3),val2-arr1-arr2-arr3-3(2)(1)(3)
val1,val3,val2-2,val2-arr1-1(2),val2-arr1-arr2-1(2)(2),val2-arr1-arr2-3(2)(2),val2-arr1-arr2-arr3-1(2)(2)(1),val2-arr1-arr2-arr3-2(2)(2)(1),val2-arr1-arr2-arr3-3(2)(2)(1)
val1,val3,val2-2,val2-arr1-1(2),val2-arr1-arr2-1(2)(2),val2-arr1-arr2-3(2)(2),val2-arr1-arr2-arr3-1(2)(2)(2),val2-arr1-arr2-arr3-2(2)(2)(2),val2-arr1-arr2-arr3-3(2)(2)(2)
val1,val3,val2-2,val2-arr1-1(2),val2-arr1-arr2-1(2)(2),val2-arr1-arr2-3(2)(2),val2-arr1-arr2-arr3-1(2)(2)(3),val2-arr1-arr2-arr3-2(2)(2)(3),val2-arr1-arr2-arr3-3(2)(2)(3)

Sample fiddle: https://dotnetfiddle.net/wnacwN小提琴样本: https://dotnetfiddle.net/wnacwN

Disclaimer: I'm the author of this library.免责声明:我是这个库的作者。

I leave here what I have so far, @Cinchoo我把到目前为止的东西留在这里,@Cinchoo

        public DataTable MapJson(string json)
    {
        var jo = JToken.Parse(json);
        var stringReader = new StringReader(MakeConfigString(jo));
        var serializer = new XmlSerializer(typeof(DataTableConfig));
        var config = (DataTableConfig)serializer.Deserialize(stringReader);
        var dataTable = new DataTable();

        foreach (var p in config.Property)
        {
            dataTable.Columns.Add(p.Name);
        }

        var regex = new Regex(Regex.Escape("*"));

        var count = 0;
        if (jo is JArray)
        {
            count = jo.Count();
        }
        else if (jo is JObject jsonLinq)
        {
            count = jsonLinq.Descendants().FirstOrDefault(d => d is JArray)?.Count() ?? 1;
        }

        var dataCollection = Enumerable.Range(0, count)
            .Select(x => config.Property
                .Select(prop => new KeyValuePair<string, List<string>>
                (
                    prop.Name,
                    jo.SelectTokens(regex.Replace(prop.Path, x.ToString(), 1)).Select(c => c.Value<string>()).ToList())
                ));


        foreach (var data in dataCollection)
        {
            var countMax = data.Select(x => x.Value).Max(x => x.Count);

            for (var i = 0; i < countMax; i++)
            {
                var innerList = new List<object>();
                foreach (var prop in config.Property)
                {
                    var currentData = data.Where(x => x.Key == prop.Name).SelectMany(x => x.Value).ToList();

                    if (currentData.Any())
                    {

                        if (i >= currentData.Count)
                        {
                            innerList.Add(currentData.Last());
                        }
                        else
                        {
                            innerList.Add(currentData[i]);
                        }
                    }
                    else
                    {
                        innerList.Add("");
                    }
                }

                dataTable.Rows.Add(innerList.ToArray());
            }
        }

        return dataTable;
    }
        private string MakeConfigString(JToken json)
    {
        var result = @"<DataTableConfig Name='DataTable'>";

        foreach (var col in this.ApiConnectorsColumns)
        {
            var path = json is JArray ? col.PathNode.Replace(".Columns", "[*]") : col.PathNode.Remove(0, 9);
            var temp = $"<Property Name='{col.ColumnName}' Path='{path}'/>";
            result += temp;
        }

        result += "</DataTableConfig>";

        return result;
    }
[XmlRoot(ElementName = "Property")]
public class Property
{
    [XmlAttribute(AttributeName = "Name")]
    public string Name { get; set; }
    [XmlAttribute(AttributeName = "Path")]
    public string Path { get; set; }
}
    [XmlRoot(ElementName = "DataTableConfig")]
public class DataTableConfig
{
    [XmlElement(ElementName = "Property")]
    public List<Property> Property { get; set; }
    [XmlAttribute(AttributeName = "Name")]
    public string Name { get; set; }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM