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

Groovy JSONSlurper:如何遍历多层级对象与数组?

Groovy处理固定层级JSON的实用方案

一、JSONPath vs Map:选择建议

  • 原生Map/List遍历:针对你这种层级固定(最多5层)、元素结构明确的场景,优先用Groovy原生的Map和List操作。语法直观,不需要额外引入依赖,性能更优,遇到单个对象直接取key,数组就循环遍历,调试也方便。
  • JSONPath:更适合结构不固定、需要复杂查询的场景。对于固定层级的JSON,反而会增加语法复杂度,还要额外引入Jayway JsonPath这类依赖,完全没必要。

二、获取各层级键值的方法

Groovy用JsonSlurper解析JSON后,会将对象转为LinkedHashMap,数组转为ArrayList,直接通过层级访问+循环就能拿到所有层级的键:

  1. 根层级键:json.keySet()
  2. 子层级键:
    • 若为单个对象:json.parentKey.keySet()
    • 若为数组:遍历数组元素后,对每个元素取element.keySet()

三、扁平化数据提取示例与技巧

简化版JSON示例

{
  "root": {
    "level1": [
      {
        "level2": {
          "level3": "value1",
          "level3_2": "value2"
        }
      },
      {
        "level2": {
          "level3": "value3"
        }
      }
    ],
    "level1_single": {
      "level2": {
        "level3": "value4"
      }
    }
  }
}

扁平化提取实现代码

import groovy.json.JsonSlurper

def jsonStr = '''
{
  "root": {
    "level1": [
      {
        "level2": {
          "level3": "value1",
          "level3_2": "value2"
        }
      },
      {
        "level2": {
          "level3": "value3"
        }
      }
    ],
    "level1_single": {
      "level2": {
        "level3": "value4"
      }
    }
  }
'''

def json = new JsonSlurper().parseText(jsonStr)
def flatData = []

// 处理level1数组类型节点
json.root.level1.each { level1Item ->
    def level2Node = level1Item.level2
    flatData << [
        root_key: "root",
        level1_key: "level1",
        level2_keys: level2Node.keySet().join(","),
        level3_data: level2Node.collectEntries { k, v -> [(k): v] }
    ]
}

// 处理level1单个对象类型节点
def level1SingleNode = json.root.level1_single
def level2SingleNode = level1SingleNode.level2
flatData << [
    root_key: "root",
    level1_key: "level1_single",
    level2_keys: level2SingleNode.keySet().join(","),
    level3_data: level2SingleNode.collectEntries { k, v -> [(k): v] }
]

// 输出结果
flatData.each { println it }

核心实用技巧

  • 区分对象/数组:用instanceof判断类型,数组就循环遍历,对象直接取键值,比如:
    if (node instanceof List) {
        node.each { item -> 处理逻辑 }
    } else {
        直接处理node的键值
    }
    
  • 通用递归遍历:如果不想写多层嵌套代码,可封装递归函数处理任意固定层级,自动收集扁平化数据:
    def flattenNode(def node, String currentPath = "", def result = []) {
        if (node instanceof Map) {
            node.each { k, v ->
                def newPath = currentPath ? "${currentPath}.${k}" : k
                if (v instanceof Map || v instanceof List) {
                    flattenNode(v, newPath, result)
                } else {
                    result << [full_path: newPath, key: k, value: v]
                }
            }
        } else if (node instanceof List) {
            node.eachWithIndex { item, idx ->
                flattenNode(item, "${currentPath}[${idx}]", result)
            }
        }
        return result
    }
    
    // 调用示例
    def fullFlatResult = flattenNode(json)
    fullFlatResult.each { println it }
    
  • 空指针防护:用Groovy的安全导航操作符?.,比如json.root?.level1?.each,避免某层级为null时抛出异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 11:47:27