问题
I need to implement a method that will scan a string of JSON for a particular targetField and either return the value of that field (if it exists), or null (if it doesn't):
// Ex: extractFieldValue(/{ "fizz" : "buzz" }/, 'fizz') => 'buzz'
// Ex: extractFieldValue(/{ "fizz" : "buzz" }/, 'foo') => null
String extractFieldValue(String json, String targetField) {
    // ...
}
This solution has to be recursive and work at any nesting-level in the (hierarchical) JSON string. Also it needs to work for JSON arrays as well.
My best attempt so far:
String extractFieldValue(String json, String targetField) {
    def slurper = new JsonSlurper()
    def jsonMap = slurper.parseText(json)
    jsonMap."${targetField}"
}
This only works on top-level (non-nested) JSON fields. I asked the Google Gods how to use JsonSlurper recursively, but couldn't find anything useful. Any ideas here?
回答1:
Given this input string in a variable called json:
{
    "a":"a",
    "b":{"f":"f", "g":"g"},
    "c":"c",
    "d":"d",
    "e":[{"h":"h"}, {"i":{"j":"j"}}],
}
This script:
import groovy.json.JsonSlurper
def mapOrCollection (def it) {
    it instanceof Map || it instanceof Collection
}
def findDeep(def tree, String key) {
    switch (tree) {
        case Map: return tree.findResult { k, v ->
            mapOrCollection(v)
                ? findDeep(v, key)
                : k == key
                    ? v
                    : null
        }
        case Collection: return tree.findResult { e ->
            mapOrCollection(e)
                ? findDeep(e, key)
                : null
        }
        default: return null
    }
}
('a'..'k').each { key ->
    def found = findDeep(new JsonSlurper().parseText(json), key)
    println "${key}: ${found}"
}
Gives these results:
a: a
b: null
c: c
d: d
e: null
f: f
g: g
h: h
i: null
j: j
k: null
来源:https://stackoverflow.com/questions/39973668/recursively-extracting-json-field-values-in-groovy