简体   繁体   English

C#从嵌套数组中提取JSON

[英]C# Extract JSON from nested array

I'm trying to iterate through nested JSON arrays using C# and JSON.NET. 我正在尝试使用C#和JSON.NET迭代嵌套的JSON数组。 The JSON represents categories for an online webstore - below is an example. JSON代表在线网上商店的类别 - 下面是一个例子。 My goal is to create a list of all of the names of categories. 我的目标是创建所有类别名称的列表。

{
  "id": 2,
  "parent_id": 1,
  "name": "Main Category List",
  "is_active": true,
  "position": 1,
  "level": 1,
  "product_count": 0,
  "children_data": [
    {
      "id": 9,
      "parent_id": 2,
      "name": "Mens Clothing",
      "is_active": true,
      "position": 6,
      "level": 2,
      "product_count": 0,
      "children_data": []
    },
    {
      "id": 8,
      "parent_id": 2,
      "name": "Womens Clothing",
      "is_active": true,
      "position": 7,
      "level": 2,
      "product_count": 0,
      "children_data": [
        {
          "id": 223,
          "parent_id": 8,
          "name": "Outdoor Clothing",
          "is_active": true,
          "position": 1,
          "level": 3,
          "product_count": 0,
          "children_data": []
        },
        {
          "id": 224,
          "parent_id": 8,
          "name": "Hiking Clothing",
          "is_active": true,
          "position": 2,
          "level": 3,
          "product_count": 0,
          "children_data": []
        },
        {
          "id": 596,
          "parent_id": 8,
          "name": "Dresses",
          "is_active": true,
          "position": 3,
          "level": 3,
          "product_count": 0,
          "children_data": [
            {
              "id": 694,
              "parent_id": 596,
              "name": "Summer Dresses",
              "is_active": true,
              "position": 13,
              "level": 4,
              "product_count": 0,
              "children_data": [
                {
                  "id": 720,
                  "parent_id": 694,
                  "name": "Accessories",
                  "is_active": true,
                  "position": 1,
                  "level": 5,
                  "product_count": 0,
                  "children_data": [ ]
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "id": 10,
      "parent_id": 2,
      "name": "Sale & Clearance",
      "is_active": true,
      "position": 8,
      "level": 2,
      "product_count": 0,
      "children_data": []
    }
  ]
}

There could be varying levels of categories and I need to parse every one. 可能存在不同级别的类别,我需要解析每个类别。 I want to get every category and create a map. 我想获得每个类别并创建一个地图。 For example (Main Category List --> Women's Clothing --> Outdoor Clothing). 例如(主要类别列表 - >女装 - >户外服装)。 I'm thinking I can check the depth of children data but I don't know how to keep checking deeper and deeper into the next Json object. 我想我可以检查子数据的深度,但我不知道如何更深入地检查下一个Json对象。

JObject responseObject = JObject.Parse(response.Content);


foreach (JObject category in getCatResponseObj.SelectToken("children_data"))
{
    while loop checking depth of children_data



}

This appears to be a recursively defined structure. 这似乎是递归定义的结构。 You should create a function to extract the values of each of the children so you could reuse it recursively. 您应该创建一个函数来提取每个子项的值,以便您可以递归地重用它。

IEnumerable<string> GetCategoryNames(JObject data)
{
    yield return (string)data["name"];
    foreach (var name in data["children_data"].Cast<JObject>().SelectMany(GetCategoryNames))
        yield return name;
}

Then call it on the root object to get your names putting in a list or whatever. 然后在根对象上调用它以将您的名字放入列表或其他内容。

var obj = JObject.Parse(response.Content);
var names = GetCategoryNames(obj).ToList();

Otherwise, if you want to indiscriminately get all names in the object tree, just keep in mind that SelectToken() / SelectTokens() also takes json path queries. 否则,如果您想不加区分地获取对象树中的所有名称,请记住SelectToken() / SelectTokens()也需要json路径查询。 So to get all names of all descendants, you'd just do this: 因此,要获得所有后代的所有名称,您只需执行以下操作:

let names = obj.SelectTokens("..name").ToList();

Were it me, I would create the most complete JSON file I can come up with (including all possible entries), then use json2csharp or an equivalent tool to create c# classes then deserialize the Json and work with it natively. 如果是我,我会创建我能提出的最完整的JSON文件(包括所有可能的条目),然后使用json2csharp或等效工具来创建c#类,然后反序列化Json并本地使用它。 You may have to massage the results a bit - but I think you can get there. 你可能不得不按摩结果 - 但我认为你可以到达那里。 If that didn't work, I would use Newtonsofts JSON LINQ Features (documentation) . 如果这不起作用,我会使用Newtonsofts JSON LINQ功能(文档) JToken gives you parent / children combinations that allows you to traverse up and down the tree. JToken为您提供父/子组合,允许您在树上上下移动。 The samples in the documentation are really good, so no need of my filling up the page with duplicate info. 文档中的示例非常好,因此无需填写带有重复信息的页面。

(Generated from your example) (根据你的例子生成)

public class ChildrenData
{
    public int id { get; set; }
    public int parent_id { get; set; }
    public string name { get; set; }
    public bool is_active { get; set; }
    public int position { get; set; }
    public int level { get; set; }
    public int product_count { get; set; }
    public List<object> children_data { get; set; }
}

public class RootObject
{
    public int id { get; set; }
    public int parent_id { get; set; }
    public string name { get; set; }
    public bool is_active { get; set; }
    public int position { get; set; }
    public int level { get; set; }
    public int product_count { get; set; }
    public List<ChildrenData> children_data { get; set; }
}

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

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