如何用Groovy JsonSlurper替代Python循环提取JSON中的userId?
Groovy中用JsonSlurper提取userId的正确方式
你遇到的问题核心在于**actions是一个数组,里面的元素并非都包含causes字段**,直接用链式访问jenkins_data.actions.causes.userId会因为数组中存在无causes的元素而返回null。我们需要复刻Python代码里的两层遍历逻辑,逐个检查元素是否包含目标字段。
复刻Python逻辑的Groovy代码
这是和你原来Python代码完全对应的实现:
def jenkins_data = new JsonSlurper().parseText(obj) // 遍历actions数组中的每个action jenkins_data.actions.each { action -> // 先判断当前action是否有causes字段 if (action.containsKey('causes')) { // 遍历该action下的causes数组 action.causes.each { cause -> // 检查cause是否包含userId字段 if (cause.containsKey('userId')) { // 提取userId,这里可以赋值给你需要的变量 def targetUserId = cause.userId println "提取到的userId: ${targetUserId}" // 如果只需要第一个找到的userId,可以在这里终止遍历 // return // 跳出当前each循环 } } } }
为什么直接链式访问会失败?
你看到jenkins_data.actions.causes返回包含null的列表,是因为Groovy的GPath表达式特性:当你对一个List调用属性(比如.causes),Groovy会自动遍历List中的每个元素,尝试获取该属性,没有该属性的元素就返回null,最终组成一个新的List。
这时候再追加.userId,就是对这个新List里的每个元素(包括null)取userId,null调用属性自然返回null,所以你得到的结果是null。
简化版:用Groovy的集合方法快速提取
如果你只需要找到第一个存在的userId,可以用findResult和安全导航操作符?.简化代码,避免多层嵌套:
def jenkins_data = new JsonSlurper().parseText(obj) def userId = jenkins_data.actions.findResult { action -> // 用?.避免action没有causes时抛出空指针 action.causes?.find { cause -> // 找到包含userId的cause cause.containsKey('userId') }?.userId } println "提取到的第一个userId: ${userId}"
这个版本会自动遍历actions,找到第一个包含有效userId的元素并返回值,找不到则返回null,代码更简洁。
内容的提问来源于stack exchange,提问作者Benihana
相关产品推荐
相关产品推荐

