13 changed files with 791 additions and 0 deletions
@ -0,0 +1,83 @@ |
|||||||
|
package com.jayway.jsonpath; |
||||||
|
|
||||||
|
|
||||||
|
import com.jayway.jsonpath.filter.JsonPathFilterChain; |
||||||
|
import org.json.simple.parser.JSONParser; |
||||||
|
import org.json.simple.parser.ParseException; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import static java.lang.String.format; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by IntelliJ IDEA. |
||||||
|
* User: kallestenflo |
||||||
|
* Date: 2/2/11 |
||||||
|
* Time: 1:03 PM |
||||||
|
*/ |
||||||
|
public class JsonPath { |
||||||
|
|
||||||
|
private static final JSONParser JSON_PARSER = new JSONParser(); |
||||||
|
|
||||||
|
private JsonPathFilterChain filters; |
||||||
|
|
||||||
|
public static JsonPath compile(String jsonPath) { |
||||||
|
return new JsonPath(jsonPath); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private JsonPath(String jsonPath) { |
||||||
|
this.filters = new JsonPathFilterChain(PathUtil.splitPath(jsonPath)); |
||||||
|
} |
||||||
|
|
||||||
|
public <T> List<T> read(Object json) { |
||||||
|
return (List<T>) filters.filter(json); |
||||||
|
} |
||||||
|
|
||||||
|
public <T> List<T> read(String json) throws java.text.ParseException { |
||||||
|
Object root = null; |
||||||
|
try { |
||||||
|
root = JSON_PARSER.parse(json); |
||||||
|
} catch (ParseException e) { |
||||||
|
throw new java.text.ParseException(json, e.getPosition()); |
||||||
|
} |
||||||
|
return (List<T>) filters.filter(root); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static <T> List<T> read(String json, String jsonPath) throws java.text.ParseException { |
||||||
|
JsonPath path = compile(jsonPath); |
||||||
|
|
||||||
|
return path.read(json); |
||||||
|
} |
||||||
|
|
||||||
|
public static <T> List<T> read(Object json, String jsonPath) throws java.text.ParseException { |
||||||
|
JsonPath path = compile(jsonPath); |
||||||
|
|
||||||
|
return path.read(json); |
||||||
|
} |
||||||
|
|
||||||
|
public static <T> T readOne(String json, String jsonPath) throws java.text.ParseException { |
||||||
|
JsonPath path = compile(jsonPath); |
||||||
|
|
||||||
|
List<Object> result = read(json, jsonPath); |
||||||
|
|
||||||
|
if (result.size() != 1) { |
||||||
|
throw new RuntimeException(format("Expected one result when reading path: %s but was: ", jsonPath, result.size())); |
||||||
|
} |
||||||
|
|
||||||
|
return (T) result.get(0); |
||||||
|
} |
||||||
|
|
||||||
|
public static <T> T readOne(Object json, String jsonPath) throws java.text.ParseException { |
||||||
|
JsonPath path = compile(jsonPath); |
||||||
|
|
||||||
|
List<Object> result = read(json, jsonPath); |
||||||
|
|
||||||
|
if (result.size() != 1) { |
||||||
|
throw new RuntimeException(format("Expected one result when reading path: %s but was: ", jsonPath, result.size())); |
||||||
|
} |
||||||
|
|
||||||
|
return (T) result.get(0); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
package com.jayway.jsonpath; |
||||||
|
|
||||||
|
import org.json.simple.JSONArray; |
||||||
|
import org.json.simple.JSONObject; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by IntelliJ IDEA. |
||||||
|
* User: kallestenflo |
||||||
|
* Date: 2/2/11 |
||||||
|
* Time: 2:33 PM |
||||||
|
*/ |
||||||
|
public class PathItem { |
||||||
|
|
||||||
|
private final String path; |
||||||
|
|
||||||
|
private final Object target; |
||||||
|
|
||||||
|
public PathItem(String path, Object target) { |
||||||
|
this.path = path; |
||||||
|
this.target = target; |
||||||
|
} |
||||||
|
|
||||||
|
public String getPath() { |
||||||
|
return path; |
||||||
|
} |
||||||
|
|
||||||
|
public Object getTarget() { |
||||||
|
return target; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,60 @@ |
|||||||
|
package com.jayway.jsonpath; |
||||||
|
|
||||||
|
import org.json.simple.JSONArray; |
||||||
|
import org.json.simple.JSONObject; |
||||||
|
|
||||||
|
import java.util.LinkedList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by IntelliJ IDEA. |
||||||
|
* User: kallestenflo |
||||||
|
* Date: 2/2/11 |
||||||
|
* Time: 2:08 PM |
||||||
|
*/ |
||||||
|
public class PathUtil { |
||||||
|
|
||||||
|
public static boolean isContainer(Object obj) { |
||||||
|
return (isArray(obj) || isDocument(obj)); |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isArray(Object obj) { |
||||||
|
return (obj instanceof JSONArray); |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean isDocument(Object obj) { |
||||||
|
return (obj instanceof JSONObject); |
||||||
|
} |
||||||
|
|
||||||
|
public static JSONArray toArray(Object array) { |
||||||
|
return (JSONArray) array; |
||||||
|
} |
||||||
|
|
||||||
|
public static JSONObject toDocument(Object document) { |
||||||
|
return (JSONObject) document; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static List<String> splitPath(String jsonPath) { |
||||||
|
|
||||||
|
LinkedList<String> fragments = new LinkedList<String>(); |
||||||
|
|
||||||
|
if (!jsonPath.startsWith("$.")) { |
||||||
|
jsonPath = "$." + jsonPath; |
||||||
|
} |
||||||
|
|
||||||
|
jsonPath = jsonPath.replace("..", ".~.") |
||||||
|
.replace("[", ".[") |
||||||
|
.replace("@.", "@"); |
||||||
|
|
||||||
|
String[] split = jsonPath.split("\\."); |
||||||
|
|
||||||
|
for (int i = 0; i < split.length; i++) { |
||||||
|
if(split[i].trim().isEmpty()){ |
||||||
|
continue; |
||||||
|
} |
||||||
|
fragments.add(split[i].replace("@", "@.").replace("~", "..")); |
||||||
|
} |
||||||
|
return fragments; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,24 @@ |
|||||||
|
package com.jayway.jsonpath.filter; |
||||||
|
|
||||||
|
import com.jayway.jsonpath.PathItem; |
||||||
|
import org.json.simple.JSONArray; |
||||||
|
import org.json.simple.JSONObject; |
||||||
|
|
||||||
|
import java.util.Collection; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by IntelliJ IDEA. |
||||||
|
* User: kallestenflo |
||||||
|
* Date: 2/2/11 |
||||||
|
* Time: 2:01 PM |
||||||
|
*/ |
||||||
|
public abstract class JsonPathFilterBase { |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public abstract List<Object> apply(List<Object> filter); |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
package com.jayway.jsonpath.filter; |
||||||
|
|
||||||
|
import org.json.simple.JSONArray; |
||||||
|
|
||||||
|
import java.util.Collections; |
||||||
|
import java.util.LinkedList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* User: kallestenflo |
||||||
|
* Date: 2/2/11 |
||||||
|
* Time: 2:00 PM |
||||||
|
*/ |
||||||
|
public class JsonPathFilterChain { |
||||||
|
|
||||||
|
private static final List<Object> EMPTY_LIST = Collections.unmodifiableList(new JSONArray()); |
||||||
|
|
||||||
|
private List<JsonPathFilterBase> filters; |
||||||
|
|
||||||
|
public JsonPathFilterChain(List<String> pathFragments) { |
||||||
|
filters = configureFilters(pathFragments); |
||||||
|
} |
||||||
|
|
||||||
|
private List<JsonPathFilterBase> configureFilters(List<String> pathFragments) { |
||||||
|
|
||||||
|
List<JsonPathFilterBase> configured = new LinkedList<JsonPathFilterBase>(); |
||||||
|
|
||||||
|
for (String pathFragment : pathFragments) { |
||||||
|
configured.add(JsonPathFilterFactory.createFilter(pathFragment)); |
||||||
|
} |
||||||
|
return configured; |
||||||
|
} |
||||||
|
|
||||||
|
public List<Object> filter(Object root) { |
||||||
|
|
||||||
|
List<Object> rootList = new JSONArray(); |
||||||
|
rootList.add(root); |
||||||
|
|
||||||
|
List<Object> result = rootList; |
||||||
|
|
||||||
|
for (JsonPathFilterBase filter : filters) { |
||||||
|
result = filter.apply(result); |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
package com.jayway.jsonpath.filter; |
||||||
|
|
||||||
|
import java.util.regex.Pattern; |
||||||
|
|
||||||
|
/** |
||||||
|
* User: kallestenflo |
||||||
|
* Date: 2/2/11 |
||||||
|
* Time: 2:03 PM |
||||||
|
*/ |
||||||
|
public class JsonPathFilterFactory { |
||||||
|
|
||||||
|
private static final Pattern ROOT_FILTER = Pattern.compile("\\$"); |
||||||
|
private static final Pattern PROPERTY_FILTER = Pattern.compile("\\w+"); |
||||||
|
private static final Pattern WILDCARD_PROPERTY_FILTER = Pattern.compile("\\*"); |
||||||
|
private static final Pattern LIST_FILTER = Pattern.compile("\\[.*?\\]"); |
||||||
|
private static final Pattern TRAVERSE_FILTER = Pattern.compile("\\.\\."); |
||||||
|
|
||||||
|
public static JsonPathFilterBase createFilter(String pathFragment){ |
||||||
|
|
||||||
|
|
||||||
|
if(ROOT_FILTER.matcher(pathFragment).matches()){ |
||||||
|
return new RootFilter(); |
||||||
|
} |
||||||
|
else if(PROPERTY_FILTER.matcher(pathFragment).matches() || WILDCARD_PROPERTY_FILTER.matcher(pathFragment).matches() ){ |
||||||
|
return new PropertyFilter(pathFragment); |
||||||
|
} |
||||||
|
else if(LIST_FILTER.matcher(pathFragment).matches()){ |
||||||
|
return new ListFilter(pathFragment); |
||||||
|
} |
||||||
|
else if(TRAVERSE_FILTER.matcher(pathFragment).matches()){ |
||||||
|
return new TraverseFilter(pathFragment); |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,177 @@ |
|||||||
|
package com.jayway.jsonpath.filter; |
||||||
|
|
||||||
|
import com.jayway.jsonpath.PathUtil; |
||||||
|
import org.json.simple.JSONArray; |
||||||
|
|
||||||
|
import java.util.LinkedList; |
||||||
|
import java.util.List; |
||||||
|
import java.util.regex.Matcher; |
||||||
|
import java.util.regex.Pattern; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by IntelliJ IDEA. |
||||||
|
* User: kallestenflo |
||||||
|
* Date: 2/2/11 |
||||||
|
* Time: 2:32 PM |
||||||
|
*/ |
||||||
|
public class ListFilter extends JsonPathFilterBase { |
||||||
|
|
||||||
|
private static final Pattern LIST_INDEX_PATTERN = Pattern.compile("\\[(\\s?\\d+\\s?,?)+\\]"); |
||||||
|
private static final Pattern LIST_PULL_PATTERN = Pattern.compile("\\[\\s?:(\\d+)\\s?\\]"); //[ :2 ]
|
||||||
|
private static final Pattern LIST_WILDCARD_PATTERN = Pattern.compile("\\[\\*\\]"); |
||||||
|
private static final Pattern LIST_TAIL_PATTERN_SHORT = Pattern.compile("\\[\\s*-\\s*(\\d+):\\s*\\]"); // [(@.length - 12)] OR [-13:]
|
||||||
|
private static final Pattern LIST_TAIL_PATTERN_LONG = Pattern.compile("\\[\\s*\\(\\s*@\\.length\\s*-\\s*(\\d+)\\s*\\)\\s*\\]"); |
||||||
|
private static final Pattern LIST_TAIL_PATTERN = Pattern.compile("(" + LIST_TAIL_PATTERN_SHORT.pattern() + "|" + LIST_TAIL_PATTERN_LONG.pattern() + ")"); |
||||||
|
private static final Pattern LIST_ITEM_HAS_PROPERTY_PATTERN = Pattern.compile("\\[\\s?\\?\\s?\\(\\s?@\\.(\\w+)\\s?\\)\\s?\\]"); |
||||||
|
|
||||||
|
private final String pathFragment; |
||||||
|
|
||||||
|
public ListFilter(String pathFragment) { |
||||||
|
this.pathFragment = pathFragment; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<Object> apply(List<Object> items) { |
||||||
|
List<Object> result = new JSONArray(); |
||||||
|
|
||||||
|
if (LIST_INDEX_PATTERN.matcher(pathFragment).matches()) { |
||||||
|
return filterByListIndex(items); |
||||||
|
} else if (LIST_WILDCARD_PATTERN.matcher(pathFragment).matches()) { |
||||||
|
return filterByWildcard(items); |
||||||
|
} else if (LIST_TAIL_PATTERN.matcher(pathFragment).matches()) { |
||||||
|
return filterByListTailIndex(items); |
||||||
|
} else if (LIST_PULL_PATTERN.matcher(pathFragment).matches()) { |
||||||
|
return filterByPullIndex(items); |
||||||
|
} else if (LIST_ITEM_HAS_PROPERTY_PATTERN.matcher(pathFragment).matches()){ |
||||||
|
return filterByItemProperty(items); |
||||||
|
} |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
private List<Object> filterByItemProperty(List<Object> items) { |
||||||
|
List<Object> result = new JSONArray(); |
||||||
|
|
||||||
|
String prop = getFilterProperty(); |
||||||
|
|
||||||
|
for (Object current : items) { |
||||||
|
for (Object item : PathUtil.toArray(current)) { |
||||||
|
|
||||||
|
if(PathUtil.isDocument(item)){ |
||||||
|
if(PathUtil.toDocument(item).containsKey(prop)) { |
||||||
|
result.add(item); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private List<Object> filterByWildcard(List<Object> items) { |
||||||
|
List<Object> result = new JSONArray(); |
||||||
|
|
||||||
|
for (Object current : items) { |
||||||
|
result.addAll(PathUtil.toArray(current)); |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
private List<Object> filterByListTailIndex(List<Object> items) { |
||||||
|
List<Object> result = new JSONArray(); |
||||||
|
|
||||||
|
|
||||||
|
for (Object current : items) { |
||||||
|
List array = PathUtil.toArray(current); |
||||||
|
result.add(array.get(getTailIndex(array.size()))); |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
private List<Object> filterByListIndex(List<Object> items) { |
||||||
|
List<Object> result = new JSONArray(); |
||||||
|
|
||||||
|
for (Object current : items) { |
||||||
|
Integer[] index = getArrayIndex(); |
||||||
|
for (int i : index) { |
||||||
|
|
||||||
|
result.add(PathUtil.toArray(current).get(i)); |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
private List<Object> filterByPullIndex(List<Object> items) { |
||||||
|
List<Object> result = new JSONArray(); |
||||||
|
|
||||||
|
for (Object current : items) { |
||||||
|
Integer[] index = getListPullIndex(); |
||||||
|
for (int i : index) { |
||||||
|
|
||||||
|
result.add(PathUtil.toArray(current).get(i)); |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
private String getFilterProperty(){ |
||||||
|
Matcher matcher = LIST_ITEM_HAS_PROPERTY_PATTERN.matcher(pathFragment); |
||||||
|
if (matcher.matches()) { |
||||||
|
return matcher.group(1); |
||||||
|
} |
||||||
|
throw new IllegalArgumentException("invalid list filter property"); |
||||||
|
} |
||||||
|
|
||||||
|
private int getTailIndex(int arraySize) { |
||||||
|
|
||||||
|
Matcher matcher = LIST_TAIL_PATTERN_SHORT.matcher(pathFragment); |
||||||
|
if (matcher.matches()) { |
||||||
|
|
||||||
|
int index = Integer.parseInt(matcher.group(1)); |
||||||
|
|
||||||
|
return arraySize - index; |
||||||
|
} |
||||||
|
matcher = LIST_TAIL_PATTERN_LONG.matcher(pathFragment); |
||||||
|
if (matcher.matches()) { |
||||||
|
|
||||||
|
int index = Integer.parseInt(matcher.group(1)); |
||||||
|
|
||||||
|
return arraySize - index; |
||||||
|
} |
||||||
|
|
||||||
|
throw new IllegalArgumentException("invalid list index"); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
private Integer[] getListPullIndex() { |
||||||
|
Matcher matcher = LIST_PULL_PATTERN.matcher(pathFragment); |
||||||
|
if (matcher.matches()) { |
||||||
|
|
||||||
|
int pullCount = Integer.parseInt(matcher.group(1)); |
||||||
|
|
||||||
|
List<Integer> result = new LinkedList<Integer>(); |
||||||
|
|
||||||
|
for (int y = 0; y < pullCount; y++) { |
||||||
|
result.add(y); |
||||||
|
} |
||||||
|
return result.toArray(new Integer[0]); |
||||||
|
} |
||||||
|
throw new IllegalArgumentException("invalid list index"); |
||||||
|
} |
||||||
|
|
||||||
|
private Integer[] getArrayIndex() { |
||||||
|
|
||||||
|
String prepared = pathFragment.replaceAll(" ", ""); |
||||||
|
prepared = prepared.substring(1, prepared.length() - 1); |
||||||
|
|
||||||
|
List<Integer> index = new LinkedList<Integer>(); |
||||||
|
|
||||||
|
String[] split = prepared.split(","); |
||||||
|
|
||||||
|
for (String s : split) { |
||||||
|
index.add(Integer.parseInt(s)); |
||||||
|
} |
||||||
|
return index.toArray(new Integer[0]); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,41 @@ |
|||||||
|
package com.jayway.jsonpath.filter; |
||||||
|
|
||||||
|
import com.jayway.jsonpath.PathUtil; |
||||||
|
import org.json.simple.JSONArray; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by IntelliJ IDEA. |
||||||
|
* User: kallestenflo |
||||||
|
* Date: 2/2/11 |
||||||
|
* Time: 2:32 PM |
||||||
|
*/ |
||||||
|
public class PropertyFilter extends JsonPathFilterBase { |
||||||
|
private final String pathFragment; |
||||||
|
|
||||||
|
public PropertyFilter(String pathFragment) { |
||||||
|
this.pathFragment = pathFragment; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<Object> apply(List<Object> filter) { |
||||||
|
List<Object> result = new JSONArray(); |
||||||
|
|
||||||
|
for (Object current : filter) { |
||||||
|
|
||||||
|
if ("*".equals(pathFragment)) { |
||||||
|
|
||||||
|
for (Object value : PathUtil.toDocument(current).values()) { |
||||||
|
result.add(value); |
||||||
|
} |
||||||
|
|
||||||
|
} else { |
||||||
|
if (PathUtil.toDocument(current).containsKey(pathFragment)) { |
||||||
|
result.add(PathUtil.toDocument(current).get(pathFragment)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
package com.jayway.jsonpath.filter; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by IntelliJ IDEA. |
||||||
|
* User: kallestenflo |
||||||
|
* Date: 2/2/11 |
||||||
|
* Time: 2:31 PM |
||||||
|
*/ |
||||||
|
public class RootFilter extends JsonPathFilterBase{ |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<Object> apply(List<Object> filter) { |
||||||
|
return filter; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
package com.jayway.jsonpath.filter; |
||||||
|
|
||||||
|
import com.jayway.jsonpath.PathUtil; |
||||||
|
import org.json.simple.JSONArray; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by IntelliJ IDEA. |
||||||
|
* User: kallestenflo |
||||||
|
* Date: 2/2/11 |
||||||
|
* Time: 2:33 PM |
||||||
|
*/ |
||||||
|
public class TraverseFilter extends JsonPathFilterBase { |
||||||
|
private final String pathFragment; |
||||||
|
|
||||||
|
public TraverseFilter(String pathFragment) { |
||||||
|
this.pathFragment = pathFragment; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<Object> apply(List<Object> filter) { |
||||||
|
List<Object> result = new JSONArray(); |
||||||
|
|
||||||
|
traverse(filter, result); |
||||||
|
|
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
private void traverse(Object container, List<Object> result) { |
||||||
|
|
||||||
|
if (PathUtil.isDocument(container)) { |
||||||
|
result.add(container); |
||||||
|
|
||||||
|
for (Object value : PathUtil.toDocument(container).values()) { |
||||||
|
if (PathUtil.isContainer(value)) { |
||||||
|
traverse(value, result); |
||||||
|
} |
||||||
|
} |
||||||
|
} else if (PathUtil.isArray(container)) { |
||||||
|
|
||||||
|
for (Object value : PathUtil.toArray(container)) { |
||||||
|
if (PathUtil.isContainer(value)) { |
||||||
|
traverse(value, result); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,150 @@ |
|||||||
|
package com.jayway.jsonpath; |
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo; |
||||||
|
import static org.hamcrest.Matchers.hasItems; |
||||||
|
import static org.junit.Assert.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by IntelliJ IDEA. |
||||||
|
* User: kallestenflo |
||||||
|
* Date: 2/2/11 |
||||||
|
* Time: 3:07 PM |
||||||
|
*/ |
||||||
|
public class JsonPathTest { |
||||||
|
|
||||||
|
public final static String DOCUMENT = |
||||||
|
"{ \"store\": {\n" + |
||||||
|
" \"book\": [ \n" + |
||||||
|
" { \"category\": \"reference\",\n" + |
||||||
|
" \"author\": \"Nigel Rees\",\n" + |
||||||
|
" \"title\": \"Sayings of the Century\",\n" + |
||||||
|
" \"price\": 8.95\n" + |
||||||
|
" },\n" + |
||||||
|
" { \"category\": \"fiction\",\n" + |
||||||
|
" \"author\": \"Evelyn Waugh\",\n" + |
||||||
|
" \"title\": \"Sword of Honour\",\n" + |
||||||
|
" \"price\": 12.99\n" + |
||||||
|
" },\n" + |
||||||
|
" { \"category\": \"fiction\",\n" + |
||||||
|
" \"author\": \"Herman Melville\",\n" + |
||||||
|
" \"title\": \"Moby Dick\",\n" + |
||||||
|
" \"isbn\": \"0-553-21311-3\",\n" + |
||||||
|
" \"price\": 8.99\n" + |
||||||
|
" },\n" + |
||||||
|
" { \"category\": \"fiction\",\n" + |
||||||
|
" \"author\": \"J. R. R. Tolkien\",\n" + |
||||||
|
" \"title\": \"The Lord of the Rings\",\n" + |
||||||
|
" \"isbn\": \"0-395-19395-8\",\n" + |
||||||
|
" \"price\": 22.99\n" + |
||||||
|
" }\n" + |
||||||
|
" ],\n" + |
||||||
|
" \"bicycle\": {\n" + |
||||||
|
" \"color\": \"red\",\n" + |
||||||
|
" \"price\": 19.95\n" + |
||||||
|
" }\n" + |
||||||
|
" }\n" + |
||||||
|
"}"; |
||||||
|
|
||||||
|
@Test |
||||||
|
public void read_document_from_root() throws Exception { |
||||||
|
|
||||||
|
|
||||||
|
JsonPath path = JsonPath.compile("$.store"); |
||||||
|
|
||||||
|
List<Object> list = path.read(DOCUMENT); |
||||||
|
|
||||||
|
System.out.println(list.toString()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void read_store_book_1() throws Exception { |
||||||
|
|
||||||
|
|
||||||
|
JsonPath path = JsonPath.compile("$.store.book[1]"); |
||||||
|
|
||||||
|
List<Object> list = path.read(DOCUMENT); |
||||||
|
|
||||||
|
System.out.println(list.toString()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void read_store_book_wildcard() throws Exception { |
||||||
|
JsonPath path = JsonPath.compile("$.store.book[*]"); |
||||||
|
|
||||||
|
List<Object> list = path.read(DOCUMENT); |
||||||
|
|
||||||
|
System.out.println(list.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void read_store_book_author() throws Exception { |
||||||
|
assertThat(JsonPath.<String>read(DOCUMENT, "$.store.book[*].author"), hasItems("Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien")); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Test |
||||||
|
public void all_authors() throws Exception { |
||||||
|
assertThat(JsonPath.<String>read(DOCUMENT, "$..author"), hasItems("Nigel Rees", "Evelyn Waugh", "Herman Melville", "J. R. R. Tolkien")); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Test |
||||||
|
public void all_store_properties() throws Exception { |
||||||
|
List<Object> itemsInStore = JsonPath.read(DOCUMENT, "$.store.*"); |
||||||
|
|
||||||
|
assertEquals(JsonPath.readOne(itemsInStore, "$.[0].[0].author"), "Nigel Rees"); |
||||||
|
assertEquals(JsonPath.readOne(itemsInStore, "$.[0][0].author"), "Nigel Rees"); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void all_prices_in_store() throws Exception { |
||||||
|
|
||||||
|
assertThat(JsonPath.<Double>read(DOCUMENT, "$.store..price"), hasItems(8.95D, 12.99D, 8.99D, 19.95D)); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void access_array_by_index_from_tail() throws Exception { |
||||||
|
|
||||||
|
assertThat(JsonPath.<String>readOne(DOCUMENT, "$..book[(@.length-1)].author"), equalTo("J. R. R. Tolkien")); |
||||||
|
assertThat(JsonPath.<String>readOne(DOCUMENT, "$..book[-1:].author"), equalTo("J. R. R. Tolkien")); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void read_store_book_index_0_and_1() throws Exception { |
||||||
|
|
||||||
|
assertThat(JsonPath.<String>read(DOCUMENT, "$.store.book[0,1].author"), hasItems("Nigel Rees", "Evelyn Waugh")); |
||||||
|
assertTrue(JsonPath.<String>read(DOCUMENT, "$.store.book[0,1].author").size() == 2); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void read_store_book_pull_first_2() throws Exception { |
||||||
|
|
||||||
|
assertThat(JsonPath.<String>read(DOCUMENT, "$.store.book[:2].author"), hasItems("Nigel Rees", "Evelyn Waugh")); |
||||||
|
assertTrue(JsonPath.<String>read(DOCUMENT, "$.store.book[:2].author").size() == 2); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void read_store_book_filter_by_isbn() throws Exception { |
||||||
|
|
||||||
|
assertThat(JsonPath.<String>read(DOCUMENT, "$.store.book[?(@.isbn)].isbn"), hasItems("0-553-21311-3", "0-395-19395-8")); |
||||||
|
assertTrue(JsonPath.<String>read(DOCUMENT, "$.store.book[?(@.isbn)].isbn").size() == 2); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void all_members_of_all_documents() throws Exception { |
||||||
|
|
||||||
|
List<String> all = JsonPath.read(DOCUMENT, "$..*"); |
||||||
|
|
||||||
|
System.out.println(StringUtils.join(all, "\n")); |
||||||
|
System.out.println(all.toString()); |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,68 @@ |
|||||||
|
package com.jayway.jsonpath; |
||||||
|
|
||||||
|
import org.apache.commons.lang.StringUtils; |
||||||
|
import org.junit.Test; |
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.hasItemInArray; |
||||||
|
import static org.hamcrest.Matchers.hasItems; |
||||||
|
import static org.junit.Assert.assertThat; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by IntelliJ IDEA. |
||||||
|
* User: kallestenflo |
||||||
|
* Date: 2/2/11 |
||||||
|
* Time: 1:22 PM |
||||||
|
*/ |
||||||
|
public class SplitPathFragmentsTest { |
||||||
|
|
||||||
|
/* |
||||||
|
1. "$..book[-1:].foo.bar" |
||||||
|
2. "$.store.book[*].author" |
||||||
|
3. "$..author" |
||||||
|
4. "$.store.*" |
||||||
|
5. "$.store..price" |
||||||
|
6. "$..book[(@.length-1)]" |
||||||
|
7. "$..book[-1:] |
||||||
|
8. "$..book[0,1]" |
||||||
|
9. "$..book[:2]" |
||||||
|
10. "$..book[?(@.isbn)]" |
||||||
|
11. "$..book[?(@.price<10)]" |
||||||
|
12. "$..*" |
||||||
|
*/ |
||||||
|
|
||||||
|
|
||||||
|
@Test |
||||||
|
public void fragments_are_split_correctly() throws Exception { |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$..book[-1:].foo.bar"), hasItems("$", "..", "[-1:]", "foo", "bar")); |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$.store.book[*].author"), hasItems("$", "store", "book", "[*]", "author")); |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$..author"), hasItems("$", "..", "author")); |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$.store.*"), hasItems("$", "store", "*")); |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$.store..price"), hasItems("$", "store", "..", "price")); |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$..book[(@.length-1)]"), hasItems("$", "..", "book", "[(@.length-1)]")); |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$..book[-1:]"), hasItems("$", "..", "book", "[-1:]")); |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$..book[0,1]"), hasItems("$", "..", "book", "[0,1]")); |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$..book[:2]"), hasItems("$", "..", "book", "[:2]")); |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$..book[?(@.isbn)]"), hasItems("$", "..", "book", "[?(@.isbn)]")); |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$..book[?(@.price<10)]"), hasItems("$", "..", "book", "[?(@.price<10)]")); |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$..*"), hasItems("$", "..", "*")); |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$.[0][1].author"), hasItems("$", "[0]", "[1]", "author")); |
||||||
|
|
||||||
|
assertThat(PathUtil.splitPath("$.[0].[1].author"), hasItems("$", "[0]", "[1]", "author")); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue