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

如何在Flutter中解析嵌套JSON树并转换为对象列表

问题:解析嵌套JSON树为全层级对象列表(Flutter)

问题背景

现有嵌套结构的JSON树,当前代码仅能解析第一层节点,需要实现全层级解析,提取每个节点的level值并转换为对象列表,用于Flutter组件。

嵌套JSON结构

{
    "children": [
        {
            "children": [],
            "id": 9,
            "level": 1,
            "name": "Zone d'audit Interne"
        },
        {
            "children": [],
            "id": 10,
            "level": 1,
            "name": "Magasin PF"
        },
        {
            "children": [],
            "id": 11,
            "level": 1,
            "name": "Magasin MP"
        },
        {
            "children": [
                {
                    "children": [],
                    "id": 14,
                    "level": 2,
                    "name": "Packaging"
                },
                {
                    "children": [],
                    "id": 15,
                    "level": 2,
                    "name": "Labelling"
                },
                {
                    "children": [],
                    "id": 16,
                    "level": 2,
                    "name": "Assemblage Acc"
                }
            ],
            "id": 12,
            "level": 1,
            "name": " U4: Assembalge Finale"
        },
        {
            "children": [
                {
                    "children": [],
                    "id": 18,
                    "level": 2,
                    "name": "Contrôle traitement"
                },
                {
                    "children": [],
                    "id": 19,
                    "level": 2,
                    "name": "Tunnel de Séchage"
                },
                {
                    "children": [],
                    "id": 20,
                    "level": 2,
                    "name": "Traitement Mécanique"
                }
            ],
            "id": 17,
            "level": 1,
            "name": "U3: Traitement"
        },
        {
            "children": [
                {
                    "children": [],
                    "id": 23,
                    "level": 2,
                    "name": "Ass_Ligne 2"
                },
                {
                    "children": [],
                    "id": 24,
                    "level": 2,
                    "name": "Ass_ligne 1"
                },
                {
                    "children": [],
                    "id": 39,
                    "level": 2,
                    "name": "BU"
                }
            ],
            "id": 21,
            "level": 1,
            "name": "U2: Assemblage SF"
        },
        {
            "children": [
                {
                    "children": [],
                    "id": 26,
                    "level": 2,
                    "name": "Mgasin Tampon"
                },
                {
                    "children": [],
                    "id": 27,
                    "level": 2,
                    "name": "Contrôle Kitting"
                }
            ],
            "id": 25,
            "level": 1,
            "name": "U1: Kitting"
        },
        {
            "children": [],
            "id": 35,
            "level": 1,
            "name": "to-delete"
        }
    ],
    "id": 8,
    "level": 0,
    "name": "DEMO"
}

当前解析代码

Future<Map<String, dynamic>?> fetchPerimeterTree(
      {required int id, required String baseUrl}) async {
    try {
      final request = http.Request(
          'GET', Uri.parse("$baseUrl${Endpoints.fetchPerim}$id/json"));
      http.StreamedResponse response = await request.send();
      if (response.statusCode == 200) {
        debugPrint("Perimeters tree fetched with success");
        var jsonData = jsonDecode(await response.stream.bytesToString());
        List<dynamic> fetchData2 = jsonData["children"];
        fetchData2.forEach((element) {
          print(element["name"]);
          print(element["children"]);
          print(element["level"]);
        });
        print(fetchData2);
        return jsonData;
      } else {
        throw Exception('Failed to load perimeter tree ${response.statusCode}');
      }
    } catch (ex) {
      debugPrint(ex.toString());
    }
  }

解决方案

1. 定义数据模型类

创建对应节点的Dart类,包含递归解析JSON的工厂方法:

class PerimeterNode {
  final int id;
  final int level;
  final String name;
  final List<PerimeterNode> children;

  PerimeterNode({
    required this.id,
    required this.level,
    required this.name,
    required this.children,
  });

  // 递归解析JSON为节点对象
  factory PerimeterNode.fromJson(Map<String, dynamic> json) {
    List<PerimeterNode> childNodes = (json['children'] as List)
        .map((childJson) => PerimeterNode.fromJson(childJson))
        .toList();

    return PerimeterNode(
      id: json['id'],
      level: json['level'],
      name: json['name'],
      children: childNodes,
    );
  }
}

2. 递归遍历并扁平化节点列表

如果需要将所有层级的节点整理为扁平列表(方便ListView等组件使用),添加递归遍历函数:

// 遍历整个节点树,收集所有节点到扁平列表
List<PerimeterNode> flattenPerimeterTree(PerimeterNode root) {
  List<PerimeterNode> allNodes = [root];
  for (var child in root.children) {
    allNodes.addAll(flattenPerimeterTree(child));
  }
  return allNodes;
}

3. 修改请求函数完成全层级解析

更新原请求函数,将JSON解析为节点对象,并按需返回扁平列表或树结构:

Future<List<PerimeterNode>?> fetchAllPerimeterNodes({required int id, required String baseUrl}) async {
  try {
    final request = http.Request(
        'GET', Uri.parse("$baseUrl${Endpoints.fetchPerim}$id/json"));
    http.StreamedResponse response = await request.send();
    
    if (response.statusCode == 200) {
      debugPrint("Perimeters tree fetched with success");
      var jsonData = jsonDecode(await response.stream.bytesToString());
      
      // 解析根节点(包含全层级子节点)
      PerimeterNode rootNode = PerimeterNode.fromJson(jsonData);
      
      // 转换为扁平节点列表
      List<PerimeterNode> allNodes = flattenPerimeterTree(rootNode);
      
      // 验证输出
      allNodes.forEach((node) {
        print("Level ${node.level}: ${node.name} (ID: ${node.id})");
      });
      
      return allNodes;
    } else {
      throw Exception('Failed to load perimeter tree ${response.statusCode}');
    }
  } catch (ex) {
    debugPrint(ex.toString());
    return null;
  }
}

说明

  • 模型类的fromJson方法通过递归处理子节点,实现全层级解析。
  • 若需保留树结构(用于树形展开组件),直接返回rootNode即可,无需调用flattenPerimeterTree。
  • 扁平列表可直接用于Flutter的列表组件,每个节点包含完整的level、id、name信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 08:30:47