0

我有以下 JSON:

{"name":"Guillaume","age":33,"address":"main st","pets":[{"type":"dog", "color":"brown"},{"type":"dog", "color":"brown"}]}}

我已经使用 JsonSlurper 来解析它。我需要能够根据各种标准修改 JSON 的内容。我要修改的键是外部定义的。

我可以轻松更改字符串值,如下所示。下面导致lazyMap中的地址字段从“main st”更改为“second 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 @ 第 1 行第 51 列的变量。 s = [city:New York, state:New York, str

但是,以下工作(将地址键值从字符串更改为 LazyMap),但需要我的键是已知的/硬编码的:

result.person.address = newAddressMap
println result.person.address.getClass()
println result.person.address

下面没有错误,但 $newAddressMap 是一个字符串,而lazyMap 键“地址”仍然是一个字符串。

Eval.me('result', result, "$address = '$newAddressMap'")
println result.person.address.getClass()
println result.person.address

如何在运行时定义地址键值的同时将地址键值从字符串更改为映射?

4

1 回答 1

0

你的意思是这样吗?

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"
            }
        ]
    }
}
于 2016-03-21T16:38:08.457 回答