Как изменить значение (и тип) записи lazymap в jsonslurped
У меня есть следующий JSON:
{"name":"Guillaume","age":33,"address":"main st","pets":[{"type":"dog", "color":"brown"},{"type":"dog", "color":"brown"}]}}
Я использовал JsonSlurper для его анализа. Мне нужно иметь возможность изменять содержимое JSON на основе различных критериев. Ключи, которые я хочу изменить, определены извне.
Я могу легко изменить строковое значение следующим образом. Ниже приведено изменение поля адреса в lazyMap с "основного st" на "второго st".
import groovy.json.JsonSlurper
def slurper = new JsonSlurper()
def result = slurper.parseText('{"person": {"name":"Guillaume","age":33,"address":"main st","pets":[{"type":"dog", "color":"brown"},{"type":"dog", "color":"brown"}]}}')
String address = "result.person.address" // Note: this is externalized
String newAddressValue = "second st"
Eval.me('result', result, "$address = '$newAddressValue'")
println result.person.address
Проблема, которую я не могу решить, состоит в том, хочу ли я изменить значение адреса со строки на карту.
import groovy.json.JsonSlurper
def slurper = new JsonSlurper()
def result = slurper.parseText('{"person": {"name":"Guillaume","age":33,"address":"main st","pets":[{"type":"dog", "color":"brown"},{"type":"dog", "color":"brown"}]}}')
Map newAddressMap = slurper.parseText(/{"street":"Third Street", "city":"New York", "state":"New York"}/)
Eval.me('result', result, "$address = $newAddressMap")
println result.person.address.getClass()
println result.person.address
$ NewAddressMap выше интерпретируется как строка, приводящая к следующей ошибке:
сбой запуска: Script1.groovy: 1: текущая область уже содержит переменную с именем York @ line 1, столбец 51. s = [город:New York, штат:New York, stre
Однако нижеприведенное работает (изменяет значение ключа адреса с String на LazyMap), но требует, чтобы мой ключ был известен / жестко закодирован:
result.person.address = newAddressMap
println result.person.address.getClass()
println result.person.address
Ниже приведена ошибка, но $newAddressMap является строкой, а ключ "address" в lazyMap остается строкой.
Eval.me('result', result, "$address = '$newAddressMap'")
println result.person.address.getClass()
println result.person.address
Как я могу изменить значение ключа адреса со строки на карту, при этом значение ключа адреса определяется во время выполнения?
1 ответ
Вы имеете в виду, как это?
import groovy.json.*
def slurper = new JsonSlurper()
// Given your document
def document = slurper.parseText('{"person": {"name":"Guillaume","age":33,"address":"main st","pets":[{"type":"dog", "color":"brown"},{"type":"dog", "color":"brown"}]}}')
// And your replacement
def newAddressMap = slurper.parseText('{"street":"Third Street", "city":"New York", "state":"New York"}')
// And the location of the attribute you want to replace
def addressPath = 'person.address'
// Split the path, and replace the property with the new map (this mutates document)
addressPath.split('\\.').with {
def parent = it[0..-2].inject(document) { d, k -> d."$k" }
parent[it[-1]] = newAddressMap
}
println new JsonBuilder(document).toPrettyString()
Какие отпечатки:
{
"person": {
"address": {
"city": "New York",
"state": "New York",
"street": "Third Street"
},
"age": 33,
"name": "Guillaume",
"pets": [
{
"color": "brown",
"type": "dog"
},
{
"color": "brown",
"type": "dog"
}
]
}
}