如何更改jsonslurped lazymap项的值(和类型)
我有以下JSON:如何更改jsonslurped lazymap项的值(和类型),json,groovy,eval,jsonslurper,Json,Groovy,Eval,Jsonslurper,我有以下JSON: {"name":"Guillaume","age":33,"address":"main st","pets":[{"type":"dog", "color":"brown"},{"type":"dog", "color":"brown"}]}} 我已经使用JsonSlurper来解析它。我需要能够根据各种标准修改JSON的内容。我要修改的键是外部定义的 我可以很容易地更改字符串值,如下所示。以下结果导致lazyMap中的地址字段从“main st”更改为“second s
{"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"}]}}')
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=[城市:新
纽约州:纽约州
但是,以下操作有效(将地址键值从字符串更改为LazyMap),但需要已知/硬编码我的键:
result.person.address = newAddressMap
println result.person.address.getClass()
println result.person.address
下面的代码没有错误,但是$newAddressMap是一个字符串,lazyMap键“address”仍然是一个字符串
Eval.me('result', result, "$address = '$newAddressMap'")
println result.person.address.getClass()
println result.person.address
在运行时定义地址键值时,如何将地址键值从字符串更改为映射?您的意思是这样的吗
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"
}
]
}
}
这是一种有趣的方法。我的实际json是嵌套的,并且有列表。我要更改的字段可能会有很大的差异。例如,我需要能够在我的json中找到并更改以下预定义占位符:活动[1]。人物[2]。地址和活动[3]。人物[0]。相对[1]。地址。执行类似Eval.me('result',result,“$address='$newAddressValue'”)它很有吸引力,因为我不必遍历json来查找字段,但它似乎仅限于更改字符串值。这些占位符来自何处?如果它们使用输入,Eval是一个相当大的安全风险,如果它们不使用,可能每个都有一个闭包会更好。此外,将此要求放在问题中会节省时间感谢您的回复。我想知道为什么我不能使用eval分配地图。占位符是通过搜索json实例并搜索配置的字段(如人员地址或相对地址)得到的。json的每个实例可能有字段,也可能没有字段。因此,它们是程序设计的Rive,不是用户提供的。我对groovy还比较陌生,非常感谢您的帮助。您能举个例子说明每个占位符的闭包是什么意思吗?您的输入帮助实现了一个解决方案,谢谢。
{
"person": {
"address": {
"city": "New York",
"state": "New York",
"street": "Third Street"
},
"age": 33,
"name": "Guillaume",
"pets": [
{
"color": "brown",
"type": "dog"
},
{
"color": "brown",
"type": "dog"
}
]
}
}