How to get the first filter element in jsonpath?

So I'm working on the bottom json:

{ "id": "", "owner": "some dude", "metaData": { "request": { "ref": null, "contacts":[ { "email": null, "name": null, "contactType": "R" }, { "email": null, "name": "Dante", "contactType": "S" } ] } } } 

I want to get the name contact that has type S and returns only the first.

Using jsonpath with this path "$..contacts[?(@.contactType == 'S')].name" always returns an array of strings because the filter operation always returns the result as an array.

So, I tried "$..contacts[?(@.contactType == 'S')].name[0]" and "$..contacts[?(@.contactType == 'S')][0].name" but no luck. This path returns empty results.

So my question is: is there a way to get only the first element when using a filter in jsonpath. I am currently using jayway jsonpath v2.2.0.

+6
source share
1 answer

If you are using jsonpath with the MockMvc class from spring -test, then you can write the following dummy layout:

 import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.core.IsEqual; import net.minidev.json.JSONArray; public class FirstMatcher<T> extends BaseMatcher<T> { private final Matcher<?> matcher; public static <T> FirstMatcher<T> matcher(Matcher<T> matcher) { return new FirstMatcher<T>(matcher); } public static FirstMatcher<Object> value(Object value) { return new FirstMatcher<Object>(value); } public FirstMatcher(Matcher<T> matcher) { this.matcher = matcher; } public FirstMatcher(Object value) { this.matcher = new IsEqual<Object>(value); } @Override public void describeTo(Description description) { description.appendText("first matcher"); } @Override public boolean matches(Object item) { if (!(item instanceof JSONArray)) { return false; } JSONArray array = (JSONArray)item; if (array.isEmpty()) { return false; } Object obj = array.get(0); return matcher.matches(obj); } } 

And use the following method:

 mockMvc. perform(get(url). accept(MediaType.APPLICATION_JSON).accept(MediaType.TEXT_PLAIN).accept(MediaType.ALL)). andExpect(status().isOk()). andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8)). andExpect(jsonPath("$.properties[?(@.propertyName == 'name1')].description").value(FirstMatcher.matcher(IsNull.nullValue()))). andExpect(jsonPath("$.properties[?(@.propertyName == 'name2')].required").value(FirstMatcher.value(true))); 

PS Since net.minidev.json.JSONArray is subclasses of java.util.List, you can list List or even Iterable rather than net.minidev.json.JSONArray. :)

0
source

Source: https://habr.com/ru/post/1013869/


All Articles