Как изменить значение (и тип) записи 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"
            }
        ]
    }
}
Другие вопросы по тегам