If I have the following JSON
[
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
]
I can get the price of "Moby Dick" using the following JSONPath:
$..[?(#.title=='Moby Dick')].price
RESULT:
'0' => "8.99"
BUT how do I do this in Mule..... what would the json expression look like to get the same result within a mule 3.2 flow?
I don't mind if your answer shows how to do it another way as long as I get the same result within mule.
Can anyone please help me with this??
The way to do that with MEL is to deserialize the JSON payload and use an MVEL filtered projection:
<json:json-to-object-transformer returnClass="java.util.List" />
<expression-transformer
expression="#[($.price in message.payload if $.title == 'Moby Dick')[0]]" />
This expression doesn't take into account cases when Moby Dick isn't present. You didn't mention what to do in that case: I can beef up the expression if you specify the desired behavior when the book's not found.
Related
having the following book store I want to find all books that match the categories 'fiction' and 'fantasy'
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "adventure",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fantasy",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
I found this example [?(#.size in ['S', ‘M'])] here which looks exactly like what I want but I could not get it working at https://jsonpath.com
This is what I tried:
$.store.book.[?(#.category in ['fiction','fantasy'])]
Looking for just a single criteria value works at https://jsonpath.com:
$.store.book.[?(#.category == 'fiction')]
Thank you for any hint pointing me into the right direction.
Try using logical OR ( || symbol) for multiple criteria.
updated expression:
$.store.book[?(#.category == 'fiction' || #.category == 'fantasy')]
Output:
Reference:
https://docs.hevodata.com/sources/engg-analytics/streaming/rest-api/writing-jsonpath-expressions/#filters
Below is the server response in a JSON format which I need to work on, In this JSON some of the objects I need to pass in the next request, which I am successfully able to do for the first occurrence, but the problem is coming on randomization in the below JSON
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sword of Honour",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "test_title",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Sword of Honour",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "India",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
if I apply $..book[0][?(#.title == 'Sword of Honour')].author condition I am seeing successful output but when I use $..book[1][?(#.title == 'Sword of Honour')].author I get a blank O/P which I understand all because at book[1] level there is not title like that.
How do I randomize the data in every Iteration so that it picks different authors for the same title? we have to take multiple values from JSON and pass it in the next request.
Extract all the titles using JSON Extractor:
It will give you the following variables:
title_1=Sword of Honour
title_2=test_title
title_3=Sword of Honour
title_4=India
title_matchNr=4
Then you can use __Random() and __V() functions combination to refer the random book title where required:
${__V(title_${__Random(1,${title_matchNr},)},)}
I have the following JSON Structure:
[
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
]
I want to get only ONE object that containts the title "The Lord of the Rings"
If i type:
$.[*].title
The output it gives me is:
[
"Sayings of the Century",
"Sword of Honour",
"Moby Dick",
"The Lord of the Rings"
]
I tried doing this:
$.[*].[?(#.title=='The Lord of the Rings')]
But it did'nt work.
Please, can someone help me?
Thanks in advance!
Excuse my previous answer. I didn't know jsonpath was a thing. I found your answer:
$[?(#.title == 'The Lord of the Rings')]
The reason is because, since the objects are in the root element, you are already trying to select the title in the elements with the #.title. When you select all elements with $.[*], you're already too low of a level to find by title.
Given the JSON below:
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century"
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3"
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": null,
"isbn": "0-395-19395-8",
"price": null
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
What JSON path could I use to retrieve the first element of book that contains a category, author, price, and title parameter? To be clear, I don't want any category, author, price, and title parameter -- only those that come from a single book object. Also, the structure of the book array varies (i.e. the number and configuration of its elements changes over time) so I can't really hardcode anything.
I think you mean you want:
$..book[?(#.category && #.author && #.price && #.title)]
How to handle when REST service response is returned as Json Array: for e.g:
[{"boolField":true,"intField":991, "StringField":"SampleString"},
{"boolField":false, "intField":998, "StringField": "SampleString2"}]";
All the blogs & examples I have seen didn't deal with the scenario mentioned above. For example, I went through http://goessner.net/articles/JsonPath/ expression syntax, but couldn't locate the solution.
For example the following json, if I want to get all the authors, I can use $.store.book[*].author or $..author
{ "store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}]}
}
However, if the REST service response is returned like below, then how to get all authors from the list
[
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
}
]
$..author will retrieve all of the authors.
In general when your root object is an array, you can think of the $ as an array and do things like $[0] to inspect the first item (You'll still get an array back however).
In my case [0].author worked (I left out the $).