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

如何实现支持多层子节点的JSON菜单指定节点链提取?

多级嵌套JSON菜单节点提取方案

需求说明

根据传入的节点链列表,从给定的多级嵌套JSON菜单结构中提取指定节点,忽略未在列表中的节点,生成新的JSON对象。节点链中的“.”表示层级关系,需保留该节点的所有子节点及完整父层级结构。

给定的Master JSON

{
  "menustructure": [
    {
      "node": "Admin",
      "path": "admin",
      "child": [
        {
          "id": "resouce0",
          "node": "Admin.resouce0",
          "path": "resouce0",
          "rank": 0,
          "child": [
            {
              "id": "res_child",
              "node": "Admin.resouce0.res_child",
              "path": "res_child",
              "rank": 1
            },
            {
              "id": "res_child2",
              "node": "Admin.resouce0.res_child2",
              "path": "res_child",
              "rank": 1
            }
          ]
        },
        {
          "id": "resouce1",
          "node": "Admin.resouce1",
          "path": "resouce1",
          "rank": 1
        },
        {
          "id": "resouce2",
          "node": "Admin.resouce2",
          "path": "oath",
          "rank": 2
        }
      ]
    },
    {
      "node": "Workspace",
      "path": "wsp",
      "child": [
        {
          "id": "system1",
          "node": "Workspace.system1",
          "path": "sys1",
          "child": [
            {
              "id": "child1",
              "node": "Workspace.system1.child1",
              "path": "ch1"
            }
          ]
        },
        {
          "id": "system2",
          "node": "Workspace.system2",
          "path": "sys2"
        }
      ]
    }
  ]
}

示例说明

  • 传入节点链['Admin.resouce1', 'Workspace']:生成包含Admin.resouce1节点(带完整Admin父层级)和整个Workspace节点(含所有子节点)的新JSON
  • 传入节点链['Admin.resouce2', 'Workspace.system1']:提取Admin.resouce2(带Admin父层级)和Workspace.system1(带Workspace父层级及自身子节点)
  • 传入节点链['Admin']:提取完整的Admin节点及其所有子节点

现有代码问题

现有代码仅支持一级子节点提取,无法处理master->child->child或更深层级的节点提取;同时父节点已存在时的子节点追加逻辑不完善,尝试过glom库未达预期。

解决方案

采用递归遍历+目标节点集合的方式,支持任意深度的嵌套节点提取,同时自动维护父层级结构:

import json
import copy

def extract_menu_nodes(master_menu, target_node_paths):
    # 收集所有需要保留的节点(包括目标节点的所有父节点)
    target_nodes = set()
    for path in target_node_paths:
        parts = path.split('.')
        # 生成每个节点链的所有层级路径,确保父节点被保留
        for i in range(1, len(parts) + 1):
            full_node_path = '.'.join(parts[:i])
            target_nodes.add(full_node_path)
    
    # 递归过滤节点
    def filter_recursive(node):
        # 当前节点不在目标集合中,直接丢弃
        if node['node'] not in target_nodes:
            return None
        
        # 复制节点,避免修改原始数据
        filtered_node = copy.deepcopy(node)
        
        # 处理子节点
        if 'child' in filtered_node and filtered_node['child']:
            filtered_children = []
            for child in filtered_node['child']:
                processed_child = filter_recursive(child)
                if processed_child:
                    filtered_children.append(processed_child)
            
            # 更新子节点列表,无符合条件的子节点则移除child字段
            if filtered_children:
                filtered_node['child'] = filtered_children
            else:
                del filtered_node['child']
        
        return filtered_node
    
    # 处理根节点列表
    filtered_menus = []
    for root_node in master_menu['menustructure']:
        filtered_root = filter_recursive(root_node)
        if filtered_root:
            filtered_menus.append(filtered_root)
    
    return {'menustructure': filtered_menus}

# 测试示例
if __name__ == "__main__":
    # 加载原始Master JSON
    master_json = """
    {
      "menustructure": [
        {
          "node": "Admin",
          "path": "admin",
          "child": [
            {
              "id": "resouce0",
              "node": "Admin.resouce0",
              "path": "resouce0",
              "rank": 0,
              "child": [
                {
                  "id": "res_child",
                  "node": "Admin.resouce0.res_child",
                  "path": "res_child",
                  "rank": 1
                },
                {
                  "id": "res_child2",
                  "node": "Admin.resouce0.res_child2",
                  "path": "res_child",
                  "rank": 1
                }
              ]
            },
            {
              "id": "resouce1",
              "node": "Admin.resouce1",
              "path": "resouce1",
              "rank": 1
            },
            {
              "id": "resouce2",
              "node": "Admin.resouce2",
              "path": "oath",
              "rank": 2
            }
          ]
        },
        {
          "node": "Workspace",
          "path": "wsp",
          "child": [
            {
              "id": "system1",
              "node": "Workspace.system1",
              "path": "sys1",
              "child": [
                {
                  "id": "child1",
                  "node": "Workspace.system1.child1",
                  "path": "ch1"
                }
              ]
            },
            {
              "id": "system2",
              "node": "Workspace.system2",
              "path": "sys2"
            }
          ]
        }
      ]
    }
    """
    master_menu = json.loads(master_json)
    
    # 测试示例1:提取Admin.resouce1和Workspace
    targets1 = ['Admin.resouce1', 'Workspace']
    result1 = extract_menu_nodes(master_menu, targets1)
    print("示例1结果:")
    print(json.dumps(result1, indent=2))
    
    # 测试示例2:提取Admin.resouce2和Workspace.system1
    targets2 = ['Admin.resouce2', 'Workspace.system1']
    result2 = extract_menu_nodes(master_menu, targets2)
    print("\n示例2结果:")
    print(json.dumps(result2, indent=2))
    
    # 测试示例3:提取Admin
    targets3 = ['Admin']
    result3 = extract_menu_nodes(master_menu, targets3)
    print("\n示例3结果:")
    print(json.dumps(result3, indent=2))

方案优势

  • 递归处理逻辑,支持任意深度的嵌套节点提取
  • 自动收集目标节点的所有父层级,确保结构完整性
  • 仅保留目标节点及其子节点,自动过滤无关节点
  • 避免重复添加父节点,递归过程中自然完成父节点的合并

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 07:10:11