Вот рабочий пример, основанный на ваших фрагментах кода, с пояснениями ниже.
import groovy.json.JsonSlurper
def jsonString = """
{
"glossary": {
"title": "example glossary",
"GlossDiv": {
"title": "S",
"GlossList": {
"GlossEntry": {
"ID": "SGML",
"SortAs": "SGML",
"GlossTerm": "Standard Generalized Markup Language",
"Acronym": "SGML",
"Abbrev": "ISO 8879:1986",
"GlossDef": {
"para": "A meta-markup language, used to create markup languages such as DocBook.",
"GlossSeeAlso": {"data" :["GML", "XML"]}
},
"GlossSee": "markup"
}
}
}
}
}"""
def gpathList = ["glossary.GlossDiv.GlossList.GlossEntry.Abbrev", "glossary.GlossDiv.GlossList.GlossEntry.GlossSee"]
def json = new JsonSlurper().parseText(jsonString)
List splitPathAroundLastDot(String gpath) {
int lastDotIndex = gpath.lastIndexOf('.')
String path = gpath[0..lastDotIndex-1]
String token = gpath[lastDotIndex+1..gpath.size()-1]
[path,token]
}
gpathList.each{ gpath ->
String path, token
(path, token) = splitPathAroundLastDot(gpath)
Eval.me( 'json', json , "json.${path}.remove('${token}')")
}
println json
Когда вы пытаетесь json.$gpath
, он интерпретируется как поиск по карте json["$gpath"]
и возвращает ноль, поскольку этого элемента нет.
Даже если вы используете полный путь и можете это сделать, вы закончите строкой, у которой нет метода remove()
, т.е.
println json.glossary.GlossDiv.GlossList.GlossEntry.Abbrev.getClass()
напечатает класс java.lang.String. Таким образом, чтобы сделать то, что вы хотите, вы должны сделать резервную копию одного шага в документе json, для этого мы разбили gpath методом splitPathAroundLastDot
.
Чтобы оценить gpath в документе json, можно использовать метод Eval.me
, привязав значение json к переменной json и удалив элемент с карты.