[英]Groovy/Java - JSON - Update JSON through variable path
任何人都知道如何在變量路徑的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。*環境中,但如果我必須涉及外部庫,那就這樣吧。
我一臉盯着Eval的具體實現。 如果我從一開始就閱讀文檔,我的解決方案實際上很簡單。
你可以在這里找到Eval的文檔: http : //docs.groovy-lang.org/2.4.7/html/api/groovy/util/Eval.html
而不是嘗試將值賦給已評估的方法/函數,這是不合邏輯的,我想如果,您需要將所有內容集成到已計算的表達式中。 對於我所發現的,您可以在Eval函數中使用最多三個變量。
我只需要兩個。 我需要jsonbuilder對象才能獲取信息源。 我需要設定值。 路徑本身可以按原樣使用,因為它已經是評估所需要的:String。
編碼:
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項目的上下文中。
既然你願意使用庫,那么json-path就是這樣做的。
從這里致信@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())
干得好:
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()
你可以嘗試在線演示
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.