66

我有一个来自 Facebook API 的 JSON 响应,如下所示:

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

我想将 JSONPath 应用于它以仅返回具有“政治家”类别的结果。从我读过的内容来看,我似乎需要做:

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

但根据我找到的测试工具,这不起作用。我发现另一个问题表明我应该使用“eq”而不是“==”,但这也不起作用。我在这里做错了什么?

4

5 回答 5

40

您的查询看起来不错,并且您的数据和查询使用此 JsonPath解析器为我工作。另请参阅该页面上的示例查询以获取更多谓词示例。

您使用的测试工具似乎有问题。甚至来自JsonPath 站点的示例也返回了不正确的结果:

例如,给定:

{
    "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
        }
    }
}

而表达式: $.store.book[?(@.length-1)].title,该工具返回所有标题的列表。

于 2012-09-25T16:28:57.073 回答
8

我没有找到正确的 jsonpath 过滤器语法来从 json 中的名称-值对中提取值。

这是下面的语法和缩写的示例 twitter 文档。

该站点对测试很有用:

jsonpath 过滤器表达式:

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

测试文件:

{
  "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"
    } ]
  } ]
}
于 2015-04-01T13:46:32.213 回答
7

去掉引号:

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

另请参阅此Json 路径示例页面

于 2015-03-09T02:26:04.157 回答
3

浏览器测试工具虽然方便,但可能有点欺骗性。考虑:

{
  "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"
  }
}

大多数工具将其返回为 false:

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

但是当我执行反对

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

它返回真实。我建议编写一个简单的单元测试来验证而不是依赖浏览器测试工具。

于 2015-09-11T15:11:50.493 回答
0

''Alastair,你可以使用这个库和工具;反抗JS。它启用对 JSON 结构的 XPath 查询,您可以测试和验证此 XPath:

//data[category="Politician"]

DefiantJS 使用“search”方法扩展全局对象,该方法又返回一个包含匹配项的数组。在 Javascript 中,它看起来像这样:

var person = JSON.search(json_data, "//people[category='Politician']");
console.log( person[0].name );
// Barack Obama
于 2014-01-04T13:27:20.213 回答