JsonPath : filter by value in array

20,261

Solution 1

The following JSONPath will work:

$..address_components[?(@.types[0] == 'country')].long_name

Breaking it down:

  • $..address_components: focus on the address_components array
  • [?(@.types[0] == 'country')]: find the address_components sub document having a type attribute named "type" containing an array of which the first value is "country"
  • .long_name: return the long_name attribute of this sub document.

Verified using the Jayway JsonPath Evaluator and in Java:

JSONArray country = JsonPath.parse(json)
    .read("$..address_components[?(@.types[0] == 'country')].long_name");

// prints Canada
System.out.println(country.get(0));

Solution 2

The working solution offered by glytching won't anymore if country is not the first one of the types array.

You should rather use:

$..address_components[?(@.types.indexOf('country') != -1)]

It will filter by array contains country, rather than array starts with country

Share:
20,261

Related videos on Youtube

ShenM
Author by

ShenM

Updated on March 13, 2020

Comments

  • ShenM
    ShenM about 4 years

    I'm trying to filter by value an array in my Json with Jsonpath. I want to get the long_name of the country in the JSON below. In order to do that, I filter the adress_components by types[0] == "country" but it doesn't seem to work.

    The JsonPath I tried :

    $.results[0].address_components[?(@['types'][0]=="country")].long_name
    

    The result I want is : "Canada".

    The JSON :

    {
           "results" : [
              {
                 "address_components" : [
                    {
                       "long_name" : "5510-5520",
                       "short_name" : "5510-5520",
                       "types" : [ "street_number" ]
                    },
                    {
                       "long_name" : "Yonge Street",
                       "short_name" : "Yonge St",
                       "types" : [ "route" ]
                    },
                    {
                       "long_name" : "Willowdale",
                       "short_name" : "Willowdale",
                       "types" : [ "neighborhood", "political" ]
                    },
                    {
                       "long_name" : "North York",
                       "short_name" : "North York",
                       "types" : [ "political", "sublocality", "sublocality_level_1" ]
                    },
                    {
                       "long_name" : "Toronto",
                       "short_name" : "Toronto",
                       "types" : [ "locality", "political" ]
                    },
                    {
                       "long_name" : "Toronto Division",
                       "short_name" : "Toronto Division",
                       "types" : [ "administrative_area_level_2", "political" ]
                    },
                    {
                       "long_name" : "Ontario",
                       "short_name" : "ON",
                       "types" : [ "administrative_area_level_1", "political" ]
                    },
                    {
                       "long_name" : "Canada",
                       "short_name" : "CA",
                       "types" : [ "country", "political" ]
                    },
                    {
                       "long_name" : "M2N 5S3",
                       "short_name" : "M2N 5S3",
                       "types" : [ "postal_code" ]
                    }
                 ]
                }
           ],
           "status" : "OK"
    }
    

    Thank you for your help.