簡體   English   中英

Groovy / Java - JSON - 通過變量路徑更新JSON

[英]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'並繼續使用該實體。

這讓我有兩個問題:

  • 如何獲取原始json中的元素值?
  • 更一般:如何使用變量路徑更新json?

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

  • 這里下載zip文件
  • 從上面的zip中提取庫及其依賴項
  • 將它們復制到SOAPUI_HOME / bin / ext目錄下
  • 重啟SoapUI

干得好:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM