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

fambo picture fambo · Oct 13, 2016 · Viewed 7.2k times · Source

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}"

Answer

Will picture Will · Oct 13, 2016

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'