Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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')
like image 625
Drona Avatar asked Jul 30 '14 07:07

Drona


People also ask

What is JSONPath expressions?

JsonPath expressions always refer to a JSON structure in the same way as XPath expression are used in combination with an XML document. The "root member object" in JsonPath is always referred to as $ regardless if it is an object or array. JsonPath expressions can use the dot–notation.

What is array slice operator in JSONPath?

: operator is the array slice operator, so you can slice collections using the syntax [start:end:step] to return a subcollection of a collection. ( ) operator lets you pass a script expression in the underlying implementation's script language. It's not supported by every implementation of JSONPath, however.


1 Answers

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.

like image 121
shabby Avatar answered Sep 28 '22 23:09

shabby