You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# 解析嵌套分类JSON获取叶子节点ID及全层级分类路径方案

C# 嵌套分类全路径拼接实现方案

前置修正:调整实体类定义

你现有的SubCategory类中subCategories属性定义为List<object>会导致无法递归遍历子分类,需要修改为List<SubCategory>类型,修正后代码如下:

public class SubCategory
{
    public int id { get; set; }
    public string name { get; set; }
    public int parentId { get; set; }
    // 修正类型为List<SubCategory>,支持多级嵌套遍历
    public List<SubCategory> subCategories { get; set; }
}

public class Category
{
    public int id { get; set; }
    public string name { get; set; }
    public object parentId { get; set; }
    public List<SubCategory> subCategories { get; set; }
}

public class Root
{
    public List<Category> categories { get; set; }
}

核心实现逻辑

通过递归遍历分类树,每进入一级分类就拼接当前分类名到路径中,当遇到subCategories为空的叶子节点时,记录当前节点ID和完整路径。

示例完整代码(以Newtonsoft.Json反序列化为例)

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

class Program
{
    // 存储最终结果的结构
    public class CategoryLeaf
    {
        public int Id { get; set; }
        public string FullPath { get; set; }
    }

    static void Main(string[] args)
    {
        // 你的JSON字符串
        string jsonStr = @"
        {
          ""categories"": [
            {
              ""id"": 368,
              ""name"": ""Accessory "",
              ""parentId"": null,
              ""subCategories"": [
                {
                  ""id"": 396,
                  ""name"": ""Jewelery "",
                  ""parentId"": 368,
                  ""subCategories"": [
                    {
                      ""id"": 397,
                      ""name"": ""wristband"",
                      ""parentId"": 396,
                      ""subCategories"": [
                        {
                          ""id"": 1238,
                          ""name"": ""Gold wristband"",
                          ""parentId"": 397,
                          ""subCategories"": []
                        },
                        {
                          ""id"": 1239,
                          ""name"": ""Silver wristband"",
                          ""parentId"": 397,
                          ""subCategories"": []
                        },
                        {
                          ""id"": 2845,
                          ""name"": ""Steel wristband"",
                          ""parentId"": 397,
                          ""subCategories"": []
                        },
                        {
                          ""id"": 3171,
                          ""name"": ""Pearl wristband"",
                          ""parentId"": 397,
                          ""subCategories"": []
                        },
                        {
                          ""id"": 3883,
                          ""name"": ""diamond wristband"",
                          ""parentId"": 397,
                          ""subCategories"": []
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }";

        // 反序列化JSON
        Root root = JsonConvert.DeserializeObject<Root>(jsonStr);
        List<CategoryLeaf> result = new List<CategoryLeaf>();

        // 遍历顶级分类
        foreach (var topCate in root.categories)
        {
            // 初始路径为顶级分类名称,Trim掉多余空格
            string initialPath = topCate.name.Trim();
            // 递归遍历子分类
            RecurseSubCate(topCate.subCategories, initialPath, result);
        }

        // 按要求格式输出
        Console.WriteLine("Id   - Name");
        Console.WriteLine("--     ----------");
        foreach (var leaf in result)
        {
            Console.WriteLine($"{leaf.Id} - {leaf.FullPath}");
        }
    }

    /// <summary>
    /// 递归遍历子分类,收集叶子节点信息
    /// </summary>
    /// <param name="subCates">当前层级分类列表</param>
    /// <param name="parentPath">上级分类拼接好的路径</param>
    /// <param name="result">结果收集集合</param>
    static void RecurseSubCate(List<SubCategory> subCates, string parentPath, List<CategoryLeaf> result)
    {
        if (subCates == null || subCates.Count == 0)
            return;

        foreach (var cate in subCates)
        {
            // 拼接当前分类到路径
            string currentPath = $"{parentPath}>{cate.name.Trim()}";
            // 判断是否为叶子节点(子分类为空)
            if (cate.subCategories == null || cate.subCategories.Count == 0)
            {
                result.Add(new CategoryLeaf
                {
                    Id = cate.id,
                    FullPath = currentPath
                });
            }
            else
            {
                // 继续递归遍历下一级
                RecurseSubCate(cate.subCategories, currentPath, result);
            }
        }
    }
}

输出效果

Id   - Name
--     ----------
1238 - Accessory>Jewelery>wristband>Gold wristband
1239 - Accessory>Jewelery>wristband>Silver wristband
2845 - Accessory>Jewelery>wristband>Steel wristband
3171 - Accessory>Jewelery>wristband>Pearl wristband
3883 - Accessory>Jewelery>wristband>diamond wristband

注意事项

  • 如果使用System.Text.Json反序列化,只需要把JsonConvert.DeserializeObject替换为JsonSerializer.Deserialize即可,逻辑无需改动
  • 代码中对分类名称做了Trim处理,避免原JSON中名称前后的多余空格影响路径格式

内容的提问来源于stack exchange,提问作者Lvnt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 04:06:04