2015-12-24 5 views
1

Я хотел бы написать единичный тест для веб-службы с помощью json-path-assert. Учитывая этот JSON:Как искать массив с использованием JSONPath в Java?

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

я хотел бы, чтобы проверить, что родитель «Некоторые называют 2» является «Некоторые из родителей 2». Я не могу изменить структуру JSON, поскольку она продиктована сторонней библиотекой.

Вот выражение JSONPath я придумал:

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

Это выражение отлично работает и дает возвращает ожидаемый результат («Некоторые из родителей 2») в this JSON tool. Однако при использовании его в Java с использованием библиотеки JSONPath я получаю пустой результат вместо правильного значения:

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> 

Не могли бы вы мне помочь с идеями, как преодолеть эту проблему?

ответ

3

Это может работать: $[?(@[2] == 'Some name 2')][1]

фона:

Если попробовать "original" JSONPath implementation написанный Stefan Goessner, следующее выражение возвращает ожидаемый массив:

$..[?(@[2] == 'Some name 2')] (потомок, где значение в индекс 2 является «Некоторое имя 2»)

===> ["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) 

библиотека JavaScript Stefan Goessner возвращает то же самое, как реализация "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/)

Гесснер является изобретателем JSONPath - поэтому его реализация делает это правильно! summary: Реализации jsonquerytool и jayway неверны.

Удивительно этот запрос работает, как ожидается, во всех реализациях (хотя $ является false в jsonquerytool)

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

также эта версия работает:

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