简体   繁体   中英

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"

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.

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.

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.

I used a inject strategy to do what you wanted:

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'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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