package com.jayway.jsonpath; import com.jayway.jsonpath.reader.PathToken; import com.jayway.jsonpath.reader.PathTokenizer; import net.minidev.json.parser.JSONParser; import net.minidev.json.parser.ParseException; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.logging.Logger; import java.util.regex.Pattern; /** * User: kalle stenflo * Date: 2/2/11 * Time: 1:03 PM *
* JsonPath is to JSON what XPATH is to XML, a simple way to extract parts of a given document. JsonPath is * available in many programming languages such as Javascript, Python and PHP. * * JsonPath allows you to compile a json path string to use it many times or to compile and apply in one * single on demand operation. * * Given the Json document: * *
* String json =
* "{
* "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
* }
* ],
* "bicycle":
* {
* "color": "red",
* "price": 19.95
* }
* }
* }";
*
*
* A JsonPath can be compiled and used as shown:
*
*
* JsonPath path = JsonPath.compile("$.store.book[1]");
*
* List<Object> books = path.read(json);
*
*
* Or:
*
*
* List<Object> authors = JsonPath.read(json, "$.store.book[*].author")
*
*
* If the json path returns a single value (is definite):
*
*
* String author = JsonPath.read(json, "$.store.book[1].author")
*
*/
public class JsonPath {
public final static int STRICT_MODE = 0;
public final static int SLACK_MODE = -1;
private static int mode = SLACK_MODE;
private final static Logger log = Logger.getLogger(JsonPath.class.getName());
private static JSONParser JSON_PARSER = new JSONParser(JsonPath.mode);
private static Pattern DEFINITE_PATH_PATTERN = Pattern.compile(".*(\\.\\.|\\*|\\[[\\\\/]|\\?|,|:\\s?\\]|\\[\\s?:|>|\\(|<|=|\\+).*");
private PathTokenizer tokenizer;
public static void setMode(int mode) {
if (mode != JsonPath.mode) {
JsonPath.mode = mode;
JSON_PARSER = new JSONParser(JsonPath.mode);
}
}
public static int getMode() {
return mode;
}
/**
* Creates a new JsonPath.
*
* @param jsonPath the path statement
*/
private JsonPath(String jsonPath) {
if (jsonPath == null ||
jsonPath.trim().isEmpty() ||
jsonPath.matches("new ") ||
jsonPath.matches("[^\\?\\+\\=\\-\\*\\/\\!]\\(")) {
throw new InvalidPathException("Invalid path");
}
this.tokenizer = new PathTokenizer(jsonPath);
//this.filters = new JsonPathFilterChain(PathUtil.splitPath(jsonPath));
}
public String getPath() {
return this.tokenizer.getPath();
}
/**
* Checks if a path points to a single item or if it potentially returns multiple items
*
* a path is considered not definite if it contains a scan fragment ".."
* or an array position fragment that is not based on a single index
*
*
* definite path examples are:
*
* $store.book
* $store.book[1].title
*
* not definite path examples are:
*
* $..book
* $.store.book[1,2]
* $.store.book[?(@.category = 'fiction')]
*
* @return true if path is definite (points to single item)
*/
public boolean isPathDefinite() {
//return !getPath().replaceAll("\"[^\"\\\\\\n\r]*\"", "").matches(".*(\\.\\.|\\*|\\[[\\\\/]|\\?|,|:\\s?\\]|\\[\\s?:|>|\\(|<|=|\\+).*");
String preparedPath = getPath().replaceAll("\"[^\"\\\\\\n\r]*\"", "");
return !DEFINITE_PATH_PATTERN.matcher(preparedPath).matches();
}
/**
* Applies this container path to the provided object
*
* @param container a container Object
* @param