任何人都知道如何使用可变路径在groovy中有效地设置json?
背景信息:我正在使用soapui,一种测试工具。有些测试是数据驱动的候选者。我有很多变数。为了使在类似情况下可以轻松实现的可持续性,我想要一个Groovy脚本,使我能够设置变量。
我将变量命名为parent.subParent.child'。
我找到了什么:
我确实找到了其他的东西,但没有记录下来。
我找到的直接的事情是评估。通过评估,可以获得值,但不能设置它们。
Eval.x(jsonbuilder, 'x.content.' + path) = 'newValue'
将返回错误。但就像我说的那样,以这种方式检索json中的值没有问题。
我尝试了什么: 我有一个适用于一个级别的实现。 我可以说:
jsonbuilder.content.parent.subParent[child] = 'newValue'
这将设置所请求实体的值。
然后我尝试将其扩展到未定义的级别。
//Assuming there is a jsonbuilder initialized
def jsonString = "{"parent":{"subParent":{"child":"oldValue"}}}"
def json = new JsonSlurper().parseText(jsonString)
def jsonbuilder = new JsonBuilder(json)
def path = 'parent.subParent.child'
def listPath = path.split("\\.")
def element = jsonbuilder.content
for(int i = 0; i < listPath.size(); i++) {
element = element[listPath[i]]
}
element = 'newValue'
assert jsonbuilder.toString() == "{"parent":{"subParent":{"child":"newValue"}}}"
问题:原始json中的值未更新。可能因为我将jsonbuilder变量分配给'element'并继续使用该实体。
这让我有两个问题:
jsonbuilder的基本JSON赋值函数如下所示:jsonbuilder.content.parent.subParent.child = 'newValue'
如下面的答案之一所给出的并不是我所关注的。我正在寻找一种让整个事物充满活力的方法。我不想建立一个已经存在且运行良好的简单任务。我正在寻找一个为我做作业的机器,将变量名称解析为路径。最好是在groovy.json。*环境中,但如果我必须涉及外部库,那就这样吧。
答案 0 :(得分:2)
我一脸盯着Eval的具体实现。如果我从一开始就阅读文档,我的解决方案实际上很简单。
您可以在此处找到Eval的文档:http://docs.groovy-lang.org/2.4.7/html/api/groovy/util/Eval.html
我没有尝试将值赋给已评估的方法/函数,而现在我认为这是不合逻辑的,您需要将所有内容集成到已计算的表达式中。对于我所发现的,您可以在Eval函数中使用最多三个变量。
我只需要两个。我需要jsonbuilder对象才能获取信息源。我需要设定值。路径本身可以按原样使用,因为它已经是评估所需要的:字符串。
代码:
import groovy.json.*
def jsonString = '{"parent":{"child":"oldValue"}}'
def newValue = 'newValue'
def stringPath = 'parent.child'
def json = new JsonSlurper().parseText(jsonString)
def jsonbuilder = new JsonBuilder(json)
Eval.xy(jsonbuilder, newValue, 'x.content.' + stringPath + '= y')
System.out.println(jsonbuilder.toString()=='{"parent":{"child":"newValue"}}')
System.out.println(jsonbuilder.content.parent.child == 'newValue')
通过使用Eval.xy(objectOne, objectTwo, StringExpression)
,我告诉我正在传递一个要作为表达式求值的字符串,其中x表示objectOne,y表示objectTwo。
可以在这里的在线groovy脚本引擎中查看代码:https://groovyconsole.appspot.com/edit/5202721384693760
小免责声明:我无法想象在代码库中使用评估表达式,它允许变量被外部世界随机操纵。如果使用这个表达式,它将舒适地放在我的SoapUI项目的上下文中。
答案 1 :(得分:1)
由于您愿意使用库,json-path会这样做。
来自here
的@kalle积分你走了:
import com.jayway.jsonpath.Configuration
import com.jayway.jsonpath.JsonPath
import com.jayway.jsonpath.spi.json.JacksonJsonNodeJsonProvider
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider
Configuration configuration = Configuration.builder()
.jsonProvider(new JacksonJsonNodeJsonProvider())
.mappingProvider(new JacksonMappingProvider())
.build()
//You need to prepend $. before the path which becomes valid jsonpath
def path = '$.parent.subParent.child'
def originalJson = """{
"parent": {
"subParent": {
"child": "oldValue"
}
}
}"""
def updatedJson = JsonPath.using(configuration).parse(originalJson).set(path, 'newValue').json()
println(updatedJson.toString())
答案 2 :(得分:0)
你走了:
import groovy.json.JsonSlurper
import groovy.json.JsonBuilder
def jsonString = """{ "parent": {
"subParent": {
"child": "oldValue"
}
}
}"""
def json = new JsonSlurper().parseText(jsonString)
def jsonbuilder = new JsonBuilder(json)
//Assign the value for child with new value
jsonbuilder.content.parent.subParent.child = 'newValue'
println jsonbuilder.toPrettyString()
您可以在线试用 Demo