简体   繁体   English

如何使用变量从Groovy中提取JSON响应中的值?

[英]How to use variable to extract value from JSON response using Groovy?

I'm trying to extract bicycle brand "Cannondale" from the JSON response by using the location of the value stored in a variable called "jsonFieldName" 我试图通过使用存储在名为“jsonFieldName”的变量中的值的位置从JSON响应中提取自行车品牌“Cannondale”

Alternatively, I'm able to successfully extract the brand value by using following syntax: 或者,我可以使用以下语法成功提取品牌价值:

def brand = json.store.bicycle.brand

however, I want to keep the location of the element in a variable. 但是,我想将元素的位置保存在变量中。 Reason being, is that I want to be able to iterate multiple assertions on the Json Response as part of my automation suite. 原因是,我希望能够在Json Response上迭代多个断言,作为我的自动化套件的一部分。

Can someone kindly advise how to do this? 有人可以建议如何做到这一点?

Below is the snippet I've currently got in place storing the location in a variable. 下面是我目前在变量中存储位置的片段。 But its not working and always returns brand as 'Null' :( Thanks. 但它不起作用,总是将品牌称为'Null':(谢谢。

def response = ('''{
   "store": {
  "book": [
     {
        "title": "Sword of Honour",
        "category": "fiction",
        "author": "Evelyn Waugh",
        "@price": 12.99
     },
     {
        "title": "Moby Dick",
        "category": "fiction",
        "author": "Herman Melville",
        "isbn": "0-553-21311-3",
        "@price": 8.99
     },
     {
        "title": "Sayings of the Century",
        "category": "reference",
        "author": "Nigel Rees",
        "@price": 8.95
     },
     {
        "title": "The Lord of the Rings",
        "category": "fiction",
        "author": "J. R. R. Tolkien",
        "isbn": "0-395-19395-8",
        "@price": 22.99
     }
  ],
  "bicycle": {
     "brand": "Cannondale",
     "color": "red",
     "price": 19.95
  }
 }
}''').toString()

//store location of json property I want to extract in property called jsonFieldName
def jsonFieldName = "store.bicycle.brand"
def json = new JsonSlurper().parseText (response)
//perform extraction
brand = json."${jsonFieldName}"

new JsonSlurper().parseText(response) returns a map , thus, searching for "store.bicycle.brand" will look for a key named store.bicycle.brand in the json variable, whilst you wanted to look first in the json['store'] and then in the index ['bicycle'] , and so on. new JsonSlurper().parseText(response)返回一个映射 ,因此,搜索"store.bicycle.brand"会在json变量中查找名为store.bicycle.brand的键,而你想在json['store']首先查找json['store']然后在索引['bicycle'] ,依此类推。

I used a inject strategy to do what you wanted: 我使用inject策略来做你想做的事:

def response = '''{
   "store": {
  "bicycle": {
     "brand": "Cannondale",
     "color": "red",
     "price": 19.95
  }
 }
}'''

def jsonFieldName = "store.bicycle.brand"
def json = new groovy.json.JsonSlurper().parseText (response)

get = { field, json2 ->
    field.tokenize(".").inject(json2) { map, f -> map[f] }
}

brand = get jsonFieldName, json
assert brand == 'Cannondale'

The problem is that using a string to access a property; 问题是使用字符串来访问属性; the string is considered the whole name of the property so you can not use it to access more than one depth property; 该字符串被视为属性的全名,因此您无法使用它来访问多个深度属性; in other words the . 换句话说. is considered part of the property name. 被视为财产名称的一部分。

A possible work around could be to split your string by the . 可能的解决方法是将字符串拆分为. character and access the properties one by one: 字符并逐个访问属性:

def jsonFieldName = "store.bicycle.brand"
def json = new JsonSlurper().parseText (response)

jsonFieldName.split("\\.").each{json = json[it]}

assert json == 'Cannondale'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM