How to filter by string in JSONPath?

2019-02-02 05:46发布

I have a JSON response from the Facebook API that looks like this:

{
  "data": [
     {
       "name": "Barack Obama", 
       "category": "Politician", 
       "id": "6815841748"
     }, 
     {
       "name": "Barack Obama's Dead Fly", 
       "category": "Public figure", 
       "id": "92943557739"
     }]
 }

I want to apply JSONPath to it to only return results with a category of "Politician". From what I've read, it appears that I need to do:

$.data[?(@.category=='Politician')]

but according to the testing tool I found, this doesn't work. I found another question which suggests that I should use "eq" instead of "==", but that doesn't work either. What am I getting wrong here?

标签: json jsonpath
5条回答
等我变得足够好
2楼-- · 2019-02-02 06:02

Drop the quotes:

List<Object> bugs = JsonPath.read(githubIssues, "$..labels[?(@.name==bug)]");

See also this Json Path Example page

查看更多
Fickle 薄情
3楼-- · 2019-02-02 06:03

I didn't find find the correct jsonpath filter syntax to extract a value from a name-value pair in json.

Here's the syntax and an abbreviated sample twitter document below.

This site was useful for testing:

The jsonpath filter expression:

.events[0].attributes[?(@.name=='screen_name')].value

Test document:

{
  "title" : "test twitter",
  "priority" : 5,
  "events" : [ {
    "eventId" : "150d3939-1bc4-4bcb-8f88-6153053a2c3e",
    "eventDate" : "2015-03-27T09:07:48-0500",
    "publisher" : "twitter",
    "type" : "tweet",
    "attributes" : [ {
      "name" : "filter_level",
      "value" : "low"
    }, {
      "name" : "screen_name",
      "value" : "_ziadin"
    }, {
      "name" : "followers_count",
      "value" : "406"
    } ]
  } ]
}
查看更多
4楼-- · 2019-02-02 06:11

Your query looks fine, and your data and query work for me using this JsonPath parser. Also see the example queries on that page for more predicate examples.

The testing tool that you're using seems faulty. Even the examples from the JsonPath site are returning incorrect results:

e.g., given:

{
    "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": "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
            }
        ],
        "bicycle":
        {
            "color": "red",
            "price": 19.95
        }
    }
}

And the expression: $.store.book[?(@.length-1)].title, the tool returns a list of all titles.

查看更多
Evening l夕情丶
5楼-- · 2019-02-02 06:22

''Alastair, you can use this lib and tool; DefiantJS. It enables XPath queries on JSON structures and you can test and validate this XPath:

//data[category="Politician"]

DefiantJS extends the global object with the method "search", which in turn returns an array with the matches. In Javascript, it'll look like this:

var person = JSON.search(json_data, "//people[category='Politician']");
console.log( person[0].name );
// Barack Obama
查看更多
欢心
6楼-- · 2019-02-02 06:23

The browser testing tools while convenient can be a bit deceiving. Consider:

{
  "resourceType": "Encounter",
  "id": "EMR56788",
  "text": {
    "status": "generated",
    "div": "Patient admitted with chest pains</div>"
  },
  "status": "in-progress",
  "class": "inpatient",
  "patient": {
    "reference": "Patient/P12345",
    "display": "Roy Batty"
  }
}

Most tools returned this as false:

$[?(@.class==inpatient)]

But when I executed against

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>1.2.0</version>
</dependency>

It returned true. I recommend writing a simple unit test to verify rather than rely on the browser testing tools.

查看更多
登录 后发表回答