**Custom Keyword** to extract the value based on json path passed as parameter in the keyword

Hi @Marek_Melocik, I am trying to create a Custom Keyword to extract the value based on json path passed as parameter in the keyword as below.

But the keyword is returning a null. Kindly help.

Null

public class getJson
{

@Keyword

public static String Value(String jsonPath)
{

  def slurper = new groovy.json.JsonSlurper()

  def result = slurper.parseText(GlobalVariable.Response.getResponseBodyContent())

  println result

  def Value = result.jsonPath
  
  println Value

  return Value
  }

}

// [TESTCASE]
// https://reqres.in/api/users?page=2
GlobalVariable.Response = WS.sendRequest(findTestObject(‘RP/UserRestService/ListUser’))

GlobalVariable.userName = CustomKeywords.‘util.getJson.Value’(‘data[1].first_name’)

System.err.println(GlobalVariable.userName)

Show me the JSON.

Hi @Russ_Thomas

data[1].first_name is Charles

I am doing something really wrong in the below line code

def Value = result.jsonPath // not working

If I directly assign the json path instead of parameter it works fine.

def Value = result.data[1].first_name // working fine

Pls note: If you copy paste the below json, you might face issue. Please replace the double quotes, using (Ctrl+h)

{
  "page":2,
  "per_page":3,
  "total":12,
  "total_pages":4,
  "data":[
    {
      "id":4,
      "first_name":"Eve",
      "last_name":"Holt",
      "avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/marcoramires/128.jpg"
    },
    {
      "id":5,
      "first_name":"Charles",
      "last_name":"Morris",
      "avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/stephenmoon/128.jpg"
    },
    {
      "id":6,
      "first_name":"Tracey",
      "last_name":"Ramos",
      "avatar":"https://s3.amazonaws.com/uifaces/faces/twitter/bigmancho/128.jpg"
    }]
}

It’s caused by using a variable in a dotted-notation. I am not a Groovy expert, but IMO it is not evaluated as ‘a-part-of-route’ to get a key in your JSON.Try to change approach in the method.

1 Like

Marek has it.

You could try passing a closure to your keyword and call it like this

CustomKeywords.‘util.getJson.Value’({data[1].first_name})

And in your keyword…

public static String Value(Closure jsonPath)
{

  def slurper = new groovy.json.JsonSlurper()

  def result = slurper.parseText(GlobalVariable.Response.getResponseBodyContent())

  return result.jsonPath()
}

I haven’t tried this but something like that might work.

But I agree with Marek… the approach is questionable at best.

Here’s what is wrong with your approach, IMO.

JsonSlurper has its own way of parsing and dispensing data from a JSON structure. To use it, you need to learn it and then operate on it.

You have decided to write your own means of accessing JSON. To do that, you first need to learn JsonSlurper and then operate on it and then add your own methods to do it your way.

Now you have TWO things to remember instead of just one. Plus, you have to maintain your methods (whereas maintaining JsonSlurper is someone else’s job).

All you’ve done is made your job harder and more expensive (time == money).

Hi @Russ_Thomas

Thanks for your reply, getting below error.

Honestly, I wish I’d never posted that idea <- because that’s all it was, an idea. It can be made to work but really, what’s the point? JsonSlurper is easy to work with and making your method work is merely an academic exercise… one I’m not prepared to complete. Sorry. Maybe someone else has the time to take it on…

Here it is again, but this time in pseudo English/code

Write a method that takes a closure as an argument.
The closure knows WHAT is to be retrieved from a JSON object.
The method handles unpacking the JSON via jsonSlurper.
Apply the closure to the JSON object and return the result.

And that’s pretty much it.