【问题标题】:How to search an array using JSONPath in Java?如何在 Java 中使用 JSONPath 搜索数组?
【发布时间】:2016-03-30 20:23:09
【问题描述】:

我想使用 json-path-assert 为 Web 服务编写单元测试。鉴于此 JSON:

[ 
  ["Some short name","Some parent","Some name"],
  ["Some short name 2","Some parent 2","Some name 2"] 
]

我想检查“Some name 2”的父级是否为“Some parent 2”。我无法更改 JSON 的结构,因为它是由第三方库指定的。

这是我想出的 JSONPath 表达式:

$..[?(@[2] == 'Some name 2')][1]

此表达式工作正常,并在this JSON tool 中返回预期结果('Some parent 2')。但是,当使用 JSONPath 库在 Java 中使用它时,我得到一个空结果而不是正确的值:

import com.jayway.jsonpath.JsonPath;
import org.junit.Test;

public class TestJSONPath
{
  @Test
  public void testJsonPath() {
     String json = "[[\"Some short name\",\"Some parent\",\"Some name\"]," +
       "[\"Some short name 2\",\"Some parent 2\",\"Some name 2\"]]";

     System.out.println(JsonPath.read(json, "$[1][1]"));    // OK, returns 'Some parent 2'
     System.out.println(JsonPath.read(json, "$..[?(@[2] == 'Some name 2')][1]")); // Not OK, returns an empty list
 }
}

这是我的 pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>test</groupId>
  <artifactId>test</artifactId>
  <version>1.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.jayway.jsonpath</groupId>
      <artifactId>json-path</artifactId>
      <version>2.1.0</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.jayway.jsonpath</groupId>
      <artifactId>json-path-assert</artifactId>
      <version>2.1.0</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

您能帮我解决这个问题吗?

【问题讨论】:

    标签: json jsonpath


    【解决方案1】:

    这可以工作: $[?(@[2] == 'Some name 2')][1]

    背景:

    如果你尝试Stefan Goessner写的"original" JSONPath implementation,下面的表达式会返回预期的数组:

    $..[?(@[2] == 'Some name 2')](索引 2 处的值为 'Some name 2' 的后代)

    ===&gt; ["Some parent 2"]

    很有趣...用 jayway、Goessners-JSON-lib 或 jsonquerytool 试试这些表达式:

    "$..*" //list of all descendants (both child-arrays + elements in arrays)
    "$.*" //list of all direct children (both child arrays)
    "$" //actual element (the array itself)
    

    Stefan Goessner 的 JavaScript 库返回与“jayway”实现相同的结果。但是“jsonquerytool”为$ 提供false - 这绝对是错误的。 $ 是“根对象/元素”。

    对于$..*,这与所有三种实现的结果相同:

    [
        [
            "Some short name",
            "Some parent",
            "Some name"
        ],
        [
            "Some short name 2",
            "Some parent 2",
            "Some name 2"
        ],
        "Some short name",
        "Some parent",
        "Some name",
        "Some short name 2",
        "Some parent 2",
        "Some name 2"
    ]
    

    所以$..[?(@[2] == 'Some name 2')] 应该匹配索引“1”处的数组...在我看来,jayway 做错了。

    使用 JSONPath 方括号对前一个路径片段寻址的对象或数组进行操作。 (见http://goessner.net/articles/JsonPath/

    Goessner 是 JSONPath 的发明者 - 所以他的实现方法是正确的!!! ? 总结: jsonquerytool 和 jayway 的实现是错误的。

    令人惊讶的是,此查询在所有实现中都按预期工作(尽管 $ 在 jsonquerytool 中是 false

    $[?(@[2] == 'Some name 2')][1]
    

    这个版本也可以:

    $.[?(@[2] == 'Some name 2')][1]
    

    【讨论】:

      猜你喜欢
      • 2018-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-16
      • 1970-01-01
      • 2013-08-09
      • 1970-01-01
      相关资源
      最近更新 更多