Drona
Drona

Reputation: 7234

JsonPath: Selecting root level field if satisfies a condition

Given the below Json input:

{ 
  "category": "fiction",
  "author": "Evelyn Waugh",
  "title": "Sword of Honour",
  "price": 12.99
}

I need to select the author field if the author matches a given name for eg. Evelyn Waugh. I am struggling to write the JsonPath Expression for this. I tried the following with no success. Can anyone suggest the correct expression?

$.author?(@ == 'Evelyn Waugh')
$.?(@.author == 'Evelyn Waugh')
$..?(@.author == 'Evelyn Waugh')

Upvotes: 15

Views: 8804

Answers (4)

Add your root object into an array before executing the query. Then this should work.

'$..[?(@.author == "Evelyn Waugh")]'

With jsonpath

import jp from 'jsonpath';

const queryResults = jp.query([yourObject], '$..[?(@.author == "Evelyn Waugh")]');

Upvotes: 0

shabby
shabby

Reputation: 3222

For me @Bernie's answer seems to work:

$[?($.author == 'Evelyn Waugh')]

It works on 3/4 json path executors (unfortunately the one not working is jsonpath.com).

The ones working are:

  1. https://codebeautify.org/jsonpath-tester
  2. https://jsonpath.herokuapp.com/
  3. WireMock (using jsonpath in java)

For those who are wondering as to why is this used and why not a plain comparison is being done here, please continue reading.

In my case I am using wiremock to simulate different server responses based on different input values of json, so for example when "author" is "Evelyn Waugh" then reply with {"books":"10"} and for all other values of "author" reply with, maybe {"books":"20"}

So the option here is only to match with a json path and this is what did the trick.

For those still wondering note that somehow wiremock doesn't work with if and else conditions, if you rely on the else condition (wildcard match) it precedes all the conditions.

Upvotes: 3

Bernie GGGG
Bernie GGGG

Reputation: 317

try $.[?($.author=='Evelyn Waugh')]

Upvotes: 4

Jeff Mercado
Jeff Mercado

Reputation: 134851

I suppose you could do this:

$[?($.author === @ && @ == 'Evelyn Waugh')]

But that's a terribly useless query and error prone if you'd ask me. It all goes to hell if there's another property with the author's name.

Frankly, you should just get the author and test if it's the name you're expecting. Don't try to force this to work, it's not meant to be used this way.

Upvotes: 1

Related Questions