javascript
JSONPath 解析 JSON 内容详解(翻译自 github)
?
Github :https://github.com/json-path/JsonPath
http://www.ibloger.net/article/2329.html
JSONPath Online Evaluator:http://jsonpath.com
?
?
JsonPath 是一種簡單的方法來提取給定JSON文檔的部分內容。 JsonPath有許多編程語言,如Javascript,Python和PHP,Java。JsonPath 提供的 json 解析非常強大,它提供了類似正則表達式的語法,基本上可以滿足所有你想要獲得的 json 內容.
JsonPath 表達式總是引用 JSON 結構,其方式與XPath表達式解析XML文檔的方式類似。JsonPath中的 “根成員對象” 總是被引用為$,不管它是對象還是數(shù)組。
JsonPath 可以使用 點 表示法:$.store.book[0].title
或者 括號 表示法:$['store']['book'][0]['title']
?
?
操作符
?
操作符 和 描述
| $ | 查詢根元素。這將開始所有路徑表達式 |
| @ | 使用過濾謂詞來處理當前節(jié)點。即過濾當前節(jié)點。 |
| * | 通配符。 任何可以使用名稱和數(shù)字的地方都可以使用。 |
| .. | 深層掃描。 任何可以使用名稱的地方都可以使用 |
| .<name> | 點,表示子節(jié)點。 |
| ['<name>' (, '<name>')] | 括號 表示子項。 |
| [<number> (, <number>)] | 數(shù)組索引 或 索引 |
| [start:end] | 數(shù)組切片操作。 |
| [?(<expression>)] | 過濾表達式。 表達式的結果必須是一個 bool 值。 |
?
?
函數(shù)
?
函數(shù)可以在路徑的末尾調用——函數(shù)的輸入是路徑表達式的輸出。函數(shù)輸出由函數(shù)本身決定。
| min() | 提供數(shù)字數(shù)組的最小值 | Double |
| max() | 提供數(shù)字數(shù)組的最大值 | Double |
| avg() | 提供數(shù)字數(shù)組的平均值 | Double |
| stddev() | 提供數(shù)字數(shù)組的標準偏差值 | Double |
| length() | 提供數(shù)組的長度 | Integer |
| sum() | 提供數(shù)字數(shù)組的所有元素的和 | Double |
?
?
過濾器運算符
?
過濾器 是 用于篩選數(shù)組的邏輯表達式。一個典型的過濾器應該是 [?(@.age > 18)],其中 @ 表示當前正在處理的項。可以使用邏輯運算符 && 和 || 創(chuàng)建更復雜的過濾器。字符串文字 必須用 單引號 或 雙引號 括起來 ([?(@.color == 'blue')] or [?(@.color == "blue")])。
| == | 左邊得值 等于 右邊的值 ( 注意:數(shù)字 1 不等于 字符串 '1' ) |
| != | 不等于 |
| < | 小于 |
| <= | 小于等于 |
| > | 大于 |
| >= | 大于等于 |
| =~ | 匹配正則表達式? [?(@.name =~ /foo.*?/i)] |
| in | 左邊 in 右邊 [?(@.size in ['S', 'M'])] |
| nin | 左邊 not in 右邊 |
| subsetof | 左邊是右邊的一個子字符串 [?(@.sizes subsetof ['S', 'M', 'L'])] |
| anyof | 左邊和右邊相交 [?(@.sizes anyof ['M', 'L'])] |
| noneof | 左邊和右邊不相交 [?(@.sizes noneof ['M', 'L'])] |
| size | (數(shù)組或字符串)長度 |
| empty | (數(shù)組或字符串)為空 |
?
?
示例
?
示例 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},{"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}},"expensive": 10 }JsonPath 表達式示例:
| $.store.book[*].author | 獲取 Json 中 store下book下的所有author值 |
| $..author | 獲取 Json 中 所有 author 的值。 |
| $.store.* | 獲取 store 下所有東西( book 和 bicycle ) |
| $.store..price | 獲取 store下以及所有子節(jié)點下的所有 price |
| $..book[2] | 獲取 book數(shù)組的第3個值 |
| $..book[-2] | 獲取 book數(shù)組的倒數(shù)第二個值 |
| $..book[0,1] | 獲取 book數(shù)組的第一、第二的值 |
| $..book[:2] | 獲取 book數(shù)組從索引 0 (包括) 到 索引 2 (不包括) 的所有值? |
| $..book[1:2] | 獲取 book數(shù)組從索引 1 (包括) 到 索引 2 (不包括) 的所有值? |
| $..book[-2:] | 獲取 book數(shù)組從索引 -2 (包括) 到 結尾 的所有值 |
| $..book[2:] | 獲取 book數(shù)組從索引 2 (包括) 到 結尾 的所有值 |
| $..book[?(@.isbn)] | 獲取 所有節(jié)點以及子節(jié)點中 book 數(shù)組包含 isbn 的所有值 |
| $.store.book[?(@.price < 10)] | 獲取 store下 book 數(shù)組中 price < 10 的所有值 |
| $..book[?(@.price <= $['expensive'])] | 獲取 所有節(jié)點以及子節(jié)點下 book 數(shù)組中 price <= expensive 的所有值 |
| $..book[?(@.author =~ /.*REES/i)] | 獲取所有匹配正則的 book ( 不區(qū)分大小寫 ) |
| $..* | 逐層列出 json 中 的所有值,層級由外到內 |
| $..book.length() | book 數(shù)組的長度 |
?
?
閱讀文檔
?
使用 JsonPath 的最簡單的最直接的方法是通過靜態(tài)讀取 API。
String json = "...";List<String> authors = JsonPath.read(json, "$.store.book[*].author");如果你只想讀取一次,那么上面的代碼就可以了。如果你還想讀取其他路徑,現(xiàn)在上面不是很好的方法,因為他每次獲取都需要再解析整個文檔。所以,我們可以先解析整個文檔,再選擇調用路徑。
String json = "..."; Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);String author0 = JsonPath.read(document, "$.store.book[0].author"); String author1 = JsonPath.read(document, "$.store.book[1].author");JsonPath還提供流暢的API。 這也是最靈活的一個。
String json = "...";ReadContext ctx = JsonPath.parse(json);List<String> authorsOfBooksWithISBN = ctx.read("$.store.book[?(@.isbn)].author");List<Map<String, Object>> expensiveBooks = JsonPath.using(configuration).parse(json).read("$.store.book[?(@.price > 10)]", List.class);?
何時返回
?
當在 java 中使用 JsonPath 時,重要的是要知道你在結果中期望什么類型。 JsonPath 將自動嘗試將結果轉換為調用者預期的類型。
//Will throw an java.lang.ClassCastException List<String> list = JsonPath.parse(json).read("$.store.book[0].author")//Works fine String author = JsonPath.parse(json).read("$.store.book[0].author")當評估路徑時,你需要理解路徑確定的概念。路徑是不確定的,它包含
-
..?:深層掃描操作
-
?(<expression>)?:表達式
-
[<number>, <number> (, <number>)]?:多個數(shù)組索引
不確定的路徑總是返回一個列表(由當前的JsonProvider表示)。
默認情況下,MappingProvider SPI提供了一個簡單的對象映射器。 這允許您指定所需的返回類型,MappingProvider將嘗試執(zhí)行映射。 在下面的示例中,演示了Long和Date之間的映射。
String json = "{\"date_as_long\" : 1411455611975}";Date date = JsonPath.parse(json).read("$['date_as_long']", Date.class);如果您將JsonPath配置為使用JacksonMappingProvider或GsonMappingProvider,您甚至可以將JsonPath輸出直接映射到POJO中。
Book book = JsonPath.parse(json).read("$.store.book[0]", Book.class);要獲取完整的泛型類型信息,請使用TypeRef。
TypeRef<List<String>> typeRef = new TypeRef<List<String>>() {};List<String> titles = JsonPath.parse(JSON_DOCUMENT).read("$.store.book[*].title", typeRef);?
謂詞
?
在JsonPath中創(chuàng)建過濾器謂詞有三種不同的方法。
?
內聯(lián)謂詞
內聯(lián)謂詞是路徑中定義的謂詞。
List<Map<String, Object>> books = JsonPath.parse(json).read("$.store.book[?(@.price < 10)]");你可以使用?&& 和 ||?結合多個謂詞 [?(@.price < 10 && @.category == 'fiction')] , [?(@.category == 'reference' || @.price > 10)].
你也可以使用!否定一個謂詞 [?(!(@.price < 10 && @.category == 'fiction'))].
?
過濾謂詞
謂詞可以使用Filter API構建,如下所示:
import static com.jayway.jsonpath.JsonPath.parse; import static com.jayway.jsonpath.Criteria.where; import static com.jayway.jsonpath.Filter.filter; ... ...Filter cheapFictionFilter = filter(where("category").is("fiction").and("price").lte(10D) );List<Map<String, Object>> books = parse(json).read("$.store.book[?]", cheapFictionFilter);注意占位符? 為路徑中的過濾器。 當提供多個過濾器時,它們按照占位符數(shù)量與提供的過濾器數(shù)量相匹配的順序應用。 您可以在一個過濾器操作[?,?]中指定多個謂詞占位符,這兩個謂詞都必須匹配。
過濾器也可以與“OR”和“AND”
Filter fooOrBar = filter(where("foo").exists(true)).or(where("bar").exists(true) );Filter fooAndBar = filter(where("foo").exists(true)).and(where("bar").exists(true) );?
自定義
第三個選擇是實現(xiàn)你自己的謂詞
Predicate booksWithISBN = new Predicate() {@Overridepublic boolean apply(PredicateContext ctx) {return ctx.item(Map.class).containsKey("isbn");} };List<Map<String, Object>> books = reader.read("$.store.book[?].isbn", List.class, booksWithISBN);?
Path vs Value
在 Goessner 實現(xiàn)中,JsonPath 可以返回 Path 或 Value。 值是默認值,上面所有示例返回。 如果你想讓我們查詢的元素的路徑可以通過選項來實現(xiàn)。
Configuration conf = Configuration.builder().options(Option.AS_PATH_LIST).build();List<String> pathList = using(conf).parse(json).read("$..author");assertThat(pathList).containsExactly("$['store']['book'][0]['author']","$['store']['book'][1]['author']","$['store']['book'][2]['author']","$['store']['book'][3]['author']");?
調整配置
?
選項創(chuàng)建配置時,有幾個可以改變默認行為的選項標志。
DEFAULT_PATH_LEAF_TO_NULL
此選項使JsonPath對于缺少的葉子返回null。 考慮下面的json
[{"name" : "john","gender" : "male"},{"name" : "ben"} ] Configuration conf = Configuration.defaultConfiguration();//Works fine String gender0 = JsonPath.using(conf).parse(json).read("$[0]['gender']"); //PathNotFoundException thrown String gender1 = JsonPath.using(conf).parse(json).read("$[1]['gender']");Configuration conf2 = conf.addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL);//Works fine String gender0 = JsonPath.using(conf2).parse(json).read("$[0]['gender']"); //Works fine (null is returned) String gender1 = JsonPath.using(conf2).parse(json).read("$[1]['gender']");?
ALWAYS_RETURN_LIST
This option configures JsonPath to return a list even when the path is?definite.
SUPPRESS_EXCEPTIONS
This option makes sure no exceptions are propagated from path evaluation. It follows these simple rules:
- If option?ALWAYS_RETURN_LIST?is present an empty list will be returned
- If option?ALWAYS_RETURN_LIST?is?NOT?present null returned
JsonProvider SPI
JsonPath is shipped with five different JsonProviders:
- JsonSmartJsonProvider?(default)
- JacksonJsonProvider
- JacksonJsonNodeJsonProvider
- GsonJsonProvider
- JsonOrgJsonProvider
Changing the configuration defaults as demonstrated should only be done when your application is being initialized. Changes during runtime is strongly discouraged, especially in multi threaded applications.
Configuration.setDefaults(new Configuration.Defaults() {private final JsonProvider jsonProvider = new JacksonJsonProvider();private final MappingProvider mappingProvider = new JacksonMappingProvider();@Overridepublic JsonProvider jsonProvider() {return jsonProvider;}@Overridepublic MappingProvider mappingProvider() {return mappingProvider;}@Overridepublic Set<Option> options() {return EnumSet.noneOf(Option.class);} });Note that the JacksonJsonProvider requires?com.fasterxml.jackson.core:jackson-databind:2.4.5?and the GsonJsonProvider requires?com.google.code.gson:gson:2.3.1?on your classpath.
?
Cache SPI
In JsonPath 2.1.0 a new Cache SPI was introduced. This allows API consumers to configure path caching in a way that suits their needs. The cache must be configured before it is accesses for the first time or a JsonPathException is thrown. JsonPath ships with two cache implementations
- com.jayway.jsonpath.spi.cache.LRUCache?(default, thread safe)
- com.jayway.jsonpath.spi.cache.NOOPCache?(no cache)
If you want to implement your own cache the API is simple.
CacheProvider.setCache(new Cache() {//Not thread safe simple cacheprivate Map<String, JsonPath> map = new HashMap<String, JsonPath>();@Overridepublic JsonPath get(String key) {return map.get(key);}@Overridepublic void put(String key, JsonPath jsonPath) {map.put(key, jsonPath);} });?
?
Java 操作示例源碼
?
示例 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},{"category": "fiction","author": "Herman Melville","title": "Moby Dick","isbn": "0-553-21311-3","price": 8.99},{"category": "JavaWeb","author": "X-rapido","title": "Top-link","isbn": "0-553-211231-3","price": 32.68},{"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}},"expensive": 10 }java 示例:
import java.io.BufferedReader; import java.io.FileReader; import java.util.Iterator; import java.util.List; import com.jayway.jsonpath.JsonPath;public class TestJsonPath {public static void main(String[] args) {String sjson = readtxt();print("--------------------------------------getJsonValue--------------------------------------");getJsonValue(sjson);}private static String readtxt() {StringBuilder sb = new StringBuilder();try {FileReader fr = new FileReader("D:/books.txt");BufferedReader bfd = new BufferedReader(fr);String s = "";while((s=bfd.readLine())!=null) {sb.append(s);}} catch (Exception e) {e.printStackTrace();}System.out.println(sb.toString());return sb.toString();}private static void getJsonValue(String json) {//The authors of all books:獲取json中store下book下的所有author值List<String> authors1 = JsonPath.read(json, "$.store.book[*].author");//All authors:獲取所有json中所有author的值List<String> authors2 = JsonPath.read(json, "$..author");//All things, both books and bicycles //authors3返回的是net.minidev.json.JSONArray:獲取json中store下的所有value值,不包含key,如key有兩個,book和bicycleList<Object> authors3 = JsonPath.read(json, "$.store.*");//The price of everything:獲取json中store下所有price的值List<Object> authors4 = JsonPath.read(json, "$.store..price");//The third book:獲取json中book數(shù)組的第3個值List<Object> authors5 = JsonPath.read(json, "$..book[2]");//The first two books:獲取json中book數(shù)組的第1和第2兩個個值List<Object> authors6 = JsonPath.read(json, "$..book[0,1]");//All books from index 0 (inclusive) until index 2 (exclusive):獲取json中book數(shù)組的前兩個區(qū)間值List<Object> authors7 = JsonPath.read(json, "$..book[:2]");//All books from index 1 (inclusive) until index 2 (exclusive):獲取json中book數(shù)組的第2個值List<Object> authors8 = JsonPath.read(json, "$..book[1:2]");//Last two books:獲取json中book數(shù)組的最后兩個值List<Object> authors9 = JsonPath.read(json, "$..book[-2:]");//Book number two from tail:獲取json中book數(shù)組的第3個到最后一個的區(qū)間值List<Object> authors10 = JsonPath.read(json, "$..book[2:]");//All books with an ISBN number:獲取json中book數(shù)組中包含isbn的所有值List<Object> authors11 = JsonPath.read(json, "$..book[?(@.isbn)]");//All books in store cheaper than 10:獲取json中book數(shù)組中price<10的所有值List<Object> authors12 = JsonPath.read(json, "$.store.book[?(@.price < 10)]");//All books in store that are not "expensive":獲取json中book數(shù)組中price<=expensive的所有值List<Object> authors13 = JsonPath.read(json, "$..book[?(@.price <= $['expensive'])]");//All books matching regex (ignore case):獲取json中book數(shù)組中的作者以REES結尾的所有值(REES不區(qū)分大小寫)List<Object> authors14 = JsonPath.read(json, "$..book[?(@.author =~ /.*REES/i)]");//Give me every thing:逐層列出json中的所有值,層級由外到內List<Object> authors15 = JsonPath.read(json, "$..*");//The number of books:獲取json中book數(shù)組的長度List<Object> authors16 = JsonPath.read(json, "$..book.length()");print("**********authors1**********");print(authors1);print("**********authors2**********");print(authors2);print("**********authors3**********");printOb(authors3);print("**********authors4**********");printOb(authors4);print("**********authors5**********");printOb(authors5);print("**********authors6**********");printOb(authors6);print("**********authors7**********");printOb(authors7);print("**********authors8**********");printOb(authors8);print("**********authors9**********");printOb(authors9);print("**********authors10**********");printOb(authors10);print("**********authors11**********");printOb(authors11);print("**********authors12**********");printOb(authors12);print("**********authors13**********");printOb(authors13);print("**********authors14**********");printOb(authors14);print("**********authors15**********");printOb(authors15);print("**********authors16**********");printOb(authors16);}private static void print(List<String> list) {for(Iterator<String> it = list.iterator();it.hasNext();) {System.out.println(it.next());}}private static void printOb(List<Object> list) {for(Iterator<Object> it = list.iterator();it.hasNext();) {System.out.println(it.next());}}private static void print(String s) {System.out.println("\n"+s);}}輸出:
{"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":"JavaWeb","author":"X-rapido","title":"Top-link","isbn":"0-553-211231-3","price":32.68},{"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}},"expensive":10}--------------------------------------getJsonValue-------------------------------------- SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/D:/workSpaces/SupportPackge/MavenRepository/org/apache/logging/log4j/log4j-slf4j-impl/2.0.2/log4j-slf4j-impl-2.0.2.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/D:/workSpaces/SupportPackge/MavenRepository/org/slf4j/slf4j-log4j12/1.7.10/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory] ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.**********authors1********** Nigel Rees Evelyn Waugh Herman Melville X-rapido J. R. R. Tolkien**********authors2********** Nigel Rees Evelyn Waugh Herman Melville X-rapido J. R. R. Tolkien**********authors3********** [{"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":"JavaWeb","author":"X-rapido","title":"Top-link","isbn":"0-553-211231-3","price":32.68},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}] {color=red, price=19.95}**********authors4********** 8.95 12.99 8.99 32.68 22.99 19.95**********authors5********** {category=fiction, author=Herman Melville, title=Moby Dick, isbn=0-553-21311-3, price=8.99}**********authors6********** {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}**********authors7********** {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}**********authors8********** {category=fiction, author=Evelyn Waugh, title=Sword of Honour, price=12.99}**********authors9********** {category=JavaWeb, author=X-rapido, title=Top-link, isbn=0-553-211231-3, price=32.68} {category=fiction, author=J. R. R. Tolkien, title=The Lord of the Rings, isbn=0-395-19395-8, price=22.99}**********authors10********** {category=fiction, author=Herman Melville, title=Moby Dick, isbn=0-553-21311-3, price=8.99} {category=JavaWeb, author=X-rapido, title=Top-link, isbn=0-553-211231-3, price=32.68} {category=fiction, author=J. R. R. Tolkien, title=The Lord of the Rings, isbn=0-395-19395-8, price=22.99}**********authors11********** {category=fiction, author=Herman Melville, title=Moby Dick, isbn=0-553-21311-3, price=8.99} {category=JavaWeb, author=X-rapido, title=Top-link, isbn=0-553-211231-3, price=32.68} {category=fiction, author=J. R. R. Tolkien, title=The Lord of the Rings, isbn=0-395-19395-8, price=22.99}**********authors12********** {category=reference, author=Nigel Rees, title=Sayings of the Century, price=8.95} {category=fiction, author=Herman Melville, title=Moby Dick, isbn=0-553-21311-3, price=8.99}**********authors13********** {category=reference, author=Nigel Rees, title=Sayings of the Century, price=8.95} {category=fiction, author=Herman Melville, title=Moby Dick, isbn=0-553-21311-3, price=8.99}**********authors14********** {category=reference, author=Nigel Rees, title=Sayings of the Century, price=8.95}**********authors15********** {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":"JavaWeb","author":"X-rapido","title":"Top-link","isbn":"0-553-211231-3","price":32.68},{"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}} 10 [{"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":"JavaWeb","author":"X-rapido","title":"Top-link","isbn":"0-553-211231-3","price":32.68},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}] {color=red, price=19.95} {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=JavaWeb, author=X-rapido, title=Top-link, isbn=0-553-211231-3, price=32.68} {category=fiction, author=J. R. R. Tolkien, title=The Lord of the Rings, isbn=0-395-19395-8, price=22.99} reference Nigel Rees Sayings of the Century 8.95 fiction Evelyn Waugh Sword of Honour 12.99 fiction Herman Melville Moby Dick 0-553-21311-3 8.99 JavaWeb X-rapido Top-link 0-553-211231-3 32.68 fiction J. R. R. Tolkien The Lord of the Rings 0-395-19395-8 22.99 red 19.95**********authors16********** 5示例 2:
import java.io.BufferedReader; import java.io.FileReader; import java.util.Iterator; import java.util.List; import java.util.Map;import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.ReadContext;public class TestJsonPath3 {public static void main(String[] args) {String sjson = readtxt();print("-----------------------getJsonValue0-----------------------");getJsonValue0(sjson);print("-----------------------getJsonValue1-----------------------");getJsonValue1(sjson);print("-----------------------getJsonValue2-----------------------");getJsonValue2(sjson);print("-----------------------getJsonValue3-----------------------");getJsonValue3(sjson);print("-----------------------getJsonValue4-----------------------");getJsonValue4(sjson);}private static String readtxt() {StringBuilder sb = new StringBuilder();try {FileReader fr = new FileReader("D:/books.txt");BufferedReader bfd = new BufferedReader(fr);String s = "";while((s=bfd.readLine())!=null) {sb.append(s);}} catch (Exception e) {e.printStackTrace();}System.out.println(sb.toString());return sb.toString();}/*** 讀取json的一種寫法,得到匹配表達式的所有值* */private static void getJsonValue0(String json) {List<String> authors = JsonPath.read(json, "$.store.book[*].author");print(authors);}/*** 讀取JSON得到某個具體值(推薦使用這種方法,一次解析多次調用)* */private static void getJsonValue1(String json) {Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);String author0 = JsonPath.read(document, "$.store.book[0].author");String author1 = JsonPath.read(document, "$.store.book[1].author");print(author0);print(author1);}/*** 讀取json的一種寫法* */private static void getJsonValue2(String json) {ReadContext ctx = JsonPath.parse(json);// 獲取json中book數(shù)組中包含isbn的作者List<String> authorsOfBooksWithISBN = ctx.read("$.store.book[?(@.isbn)].author");// 獲取json中book數(shù)組中價格大于10的對象List<Map<String, Object>> expensiveBooks = JsonPath.using(Configuration.defaultConfiguration()).parse(json).read("$.store.book[?(@.price > 10)]", List.class);print(authorsOfBooksWithISBN);print("********Map********");printListMap(expensiveBooks);}/*** 讀取JSON得到的值是一個String,所以不能用List存儲 * */private static void getJsonValue3(String json) {//Will throw an java.lang.ClassCastException //List<String> list = JsonPath.parse(json).read("$.store.book[0].author");//由于會拋異常,暫時注釋上面一行,要用的話,應使用下面的格式String author = JsonPath.parse(json).read("$.store.book[0].author");print(author);}/*** 讀取json的一種寫法,支持邏輯表達式,&&和||*/private static void getJsonValue4(String json) {List<Map<String, Object>> books1 = JsonPath.parse(json).read("$.store.book[?(@.price < 10 && @.category == 'fiction')]");List<Map<String, Object>> books2 = JsonPath.parse(json).read("$.store.book[?(@.category == 'reference' || @.price > 10)]");print("********books1********");printListMap(books1);print("********books2********");printListMap(books2);}private static void print(List<String> list) {for(Iterator<String> it = list.iterator();it.hasNext();) {System.out.println(it.next());}}private static void printListMap(List<Map<String, Object>> list) {for(Iterator<Map<String, Object>> it = list.iterator();it.hasNext();) {Map<String, Object> map = it.next();for(Iterator iterator =map.entrySet().iterator();iterator.hasNext();) {System.out.println(iterator.next());}}}private static void print(String s) {System.out.println("\n"+s);}}輸出:
{"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":"JavaWeb","author":"X-rapido","title":"Top-link","isbn":"0-553-211231-3","price":32.68},{"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}},"expensive":10}-----------------------getJsonValue0----------------------- SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/D:/workSpaces/SupportPackge/MavenRepository/org/apache/logging/log4j/log4j-slf4j-impl/2.0.2/log4j-slf4j-impl-2.0.2.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/D:/workSpaces/SupportPackge/MavenRepository/org/slf4j/slf4j-log4j12/1.7.10/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory] ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. Nigel Rees Evelyn Waugh Herman Melville X-rapido J. R. R. Tolkien-----------------------getJsonValue1-----------------------Nigel ReesEvelyn Waugh-----------------------getJsonValue2----------------------- Herman Melville X-rapido J. R. R. Tolkien********Map******** category=fiction author=Evelyn Waugh title=Sword of Honour price=12.99 category=JavaWeb author=X-rapido title=Top-link isbn=0-553-211231-3 price=32.68 category=fiction author=J. R. R. Tolkien title=The Lord of the Rings isbn=0-395-19395-8 price=22.99-----------------------getJsonValue3-----------------------Nigel Rees-----------------------getJsonValue4-----------------------********books1******** category=fiction author=Herman Melville title=Moby Dick isbn=0-553-21311-3 price=8.99********books2******** 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=JavaWeb author=X-rapido title=Top-link isbn=0-553-211231-3 price=32.68 category=fiction author=J. R. R. Tolkien title=The Lord of the Rings isbn=0-395-19395-8 price=22.99?
過濾器示例
?
java 示例:
public static void main(String[] args) {String json = readtxt();Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);// 過濾器鏈(查找包含isbn并category中有fiction或JavaWeb的值)Filter filter = Filter.filter(Criteria.where("isbn").exists(true).and("category").in("fiction", "JavaWeb"));List<Object> books = JsonPath.read(document, "$.store.book[?]", filter);printOb(books);System.out.println("\n----------------------------------------------\n");// 自定義過濾器Filter mapFilter = new Filter() {@Overridepublic boolean apply(PredicateContext context) {Map<String, Object> map = context.item(Map.class); if (map.containsKey("isbn")) {return true;}return false;}};List<Object> books2 = JsonPath.read(document, "$.store.book[?]", mapFilter);printOb(books2);}輸出:
{category=fiction, author=Herman Melville, title=Moby Dick, isbn=0-553-21311-3, price=8.99} {category=JavaWeb, author=X-rapido, title=Top-link, isbn=0-553-211231-3, price=32.68} {category=fiction, author=J. R. R. Tolkien, title=The Lord of the Rings, isbn=0-395-19395-8, price=22.99}----------------------------------------------{category=fiction, author=Herman Melville, title=Moby Dick, isbn=0-553-21311-3, price=8.99} {category=JavaWeb, author=X-rapido, title=Top-link, isbn=0-553-211231-3, price=32.68} {category=fiction, author=J. R. R. Tolkien, title=The Lord of the Rings, isbn=0-395-19395-8, price=22.99}由此可見,使用過濾器,或者使用上述的表達式,都是可以達到理想的效果
示例中的books2中,注意到context.item(Map.class); 這句話
這句中的Map.class是根據預定的結果類型定義的,如果返回的是String類型值,那就改為String.class
?
?
?
?
?
總結
以上是生活随笔為你收集整理的JSONPath 解析 JSON 内容详解(翻译自 github)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OD 快捷键使用大全。非常详细( 游戏逆
- 下一篇: Firefox、Chrome 盘助手