将CSV(嵌套对象)转换为JSON

4
我需要将一个包含一行标题和一行数据的CSV数据转换为JSON对象。 CSV包含嵌套列,这里有一个例子:
id,name,category/id,category/name,category/subcategory/id,category/subcategory/name,description
0,Test123,15,Cat123,10,SubCat123,Desc123

我希望 JSON 看起来像这样:

{
    "id": 0,
    "name": "Test123",
    "category": {
        "id": 15,
        "name": "Cat123",
        "subcategory": {
            "id": 10,
            "name": "SubCat123",
        }
    },
    "description": "Desc123"
}

我尝试了CsvHelper和ChoETL库,但没有成功,因为据我所知,这些库需要我有一个类作为模型,但我没有这些类,因为数据完全是动态的。
网站http://www.convertcsv.com/csv-to-json.htm是一个很好的例子,可以成功地完成这个过程。只需粘贴我上面创建的JSON,进入第3步,勾选“重新创建嵌套对象和数组”选项,然后在第5步中点击“CSV to JSON”。
但我需要在我的应用程序中实现这个功能,而不使用外部框架。
我该如何使它工作?

2
如果数据完全动态且您没有合理的结构期望,那么您如何指望将未知转化为已知结构呢? - maccettura
1
首先,您可以尝试构建一个字典Dictionary<string, object>,其中键是属性的名称,值可以是值本身或嵌套对象的另一个字典。棘手的部分是决定值是字符串还是整数。稍后,您可以很容易地使用JSON.Net进行序列化。 - orhtej2
2个回答

2
如果您没有它,请添加newtonsoft库(dll),然后添加以下引用。
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

添加以下类

   public class Rootobject
        {
            public int id { get; set; }
            public string name { get; set; }
            public Category category { get; set; }
            public string description { get; set; }
        }

        public class Category
        {
            public int id { get; set; }
            public string name { get; set; }
            public Subcategory subcategory { get; set; }
        }

        public class Subcategory
        {
            public int id { get; set; }
            public string name { get; set; }
        }

然后使用这段代码。
 DataTable CSVData = new DataTable(); // your csv rows



            HashSet<Rootobject> MyObjectsList = new HashSet<Rootobject>(); //create hashset to handle your classes
            foreach(DataRow row in CSVData.Rows)
            {
                //change the indices in ItemArray with the right indices
                MyObjectsList.Add(new Rootobject() {
                    id = (int)row.ItemArray[0], name = (string)row.ItemArray[0], category = new Category() {
                        id = (int)row.ItemArray[0], name = (string)row.ItemArray[0], subcategory = new Subcategory() {
                            id = (int)row.ItemArray[0], name = (string)row.ItemArray[0]
                        }
                    }
                });


            }





            string _ResultObj = JsonConvert.SerializeObject(MyObjectsList);  //here get your json string

0

有了最新的ChoETL.JSON 1.0.1.6,您可以轻松转换它们。但请注意,此方法仅适用于标题是简单文本的情况,不允许包含空格或特殊字符。

using (var json = new ChoJSONWriter("nested.json")
           .SingleElement()
           .Configure(c => c.SupportMultipleContent = true)
           .Configure(c => c.DefaultArrayHandling = false)
          )
{
    using (var csv = new ChoCSVReader("nested.csv").WithFirstLineHeader())
        json.Write(csv.Select(i => i.ConvertToNestedObject('/')));
}

输出的JSON将如下所示

[
 {
  "id":0,
  "name":"Test123",
  "category": {
    "id": 15,
    "name": "Cat123",
    "subcategory": {
      "id": 10,
      "name": "SubCat123"
    }
  },
  "description":"Desc123"
 }
]

示例代码: https://dotnetfiddle.net/vttMIB

更新:

Cinchoo ETL 现在支持原生的嵌套对象支持,只需将“NestedColumnSeparator”配置参数设置为“/”。下面的示例显示了如何设置:

using (var json = new ChoJSONWriter("nested.json")
           .SingleElement()
           .Configure(c => c.SupportMultipleContent = true)
           .Configure(c => c.DefaultArrayHandling = false)
          )
{
    using (var csv = new ChoCSVReader("nested.csv")
          .WithFirstLineHeader()
          .Configure(c => c.NestedColumnSeparator = '/')
        )
        json.Write(csv);
}

示例代码: https://dotnetfiddle.net/xFlQso


这个不再正确工作了 - 所有嵌套都创建数组 - Craig
1
用示例fiddles更正了答案。 - Cinchoo
类别是否应该是一个对象数组? - Craig
1
好的,您可以在json编写器中指定Configure(c => c.DefaultArrayHandling = false)来关闭它。已编辑答案和fiddles。谢谢。 - Cinchoo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接