JsonPath詳細(xì)使用教程,你了解多少?
Json Path介紹
看它的名字你就能知道,這Json Path和JSON文檔有關(guān)系,正如XPath之于XML文檔一樣,JsonPath為Json文檔提供了解析能力,通過使用JsonPath,你可以方便的查找節(jié)點(diǎn)、獲取想要的數(shù)據(jù),JsonPath是Json版的XPath。
JsonPath語法
- $ 表示文檔的根元素
- @ 表示文檔的當(dāng)前元素
- .node_name 或 ['node_name'] 匹配下級節(jié)點(diǎn)
- [index] 檢索數(shù)組中的元素
- [start:end:step] 支持?jǐn)?shù)組切片語法
- * 作為通配符,匹配所有成員
- .. 子遞歸通配符,匹配成員的所有子元素
- (<expr>) 使用表達(dá)式
- ?(<boolean expr>)進(jìn)行數(shù)據(jù)篩選
XPath與JsonPath比較
XPath | JsonPath | 說明 |
/ | $ | 文檔根元素 |
. | @ | 當(dāng)前元素 |
/ | .或[] | 匹配下級元素 |
.. | N/A | 匹配上級元素,JsonPath不支持此操作符 |
// | .. | 遞歸匹配所有子元素 |
* | * | 通配符,匹配下級元素 |
@ | N/A | 匹配屬性,JsonPath不支持此操作符 |
[] | [] | 下標(biāo)運(yùn)算符,根據(jù)索引獲取元素,XPath索引從1開始,JsonPath索引從0開始 |
` | ` | [,] |
N/A | [start:end:step] | 數(shù)據(jù)切片操作,XPath不支持 |
[] | ?() | 過濾表達(dá)式 |
N/A | () | 腳本表達(dá)式,使用底層腳本引擎,XPath不支持 |
() | N/A | 分組,JsonPath不支持 |
示例
下面是相應(yīng)的JsonPath的示例,代碼來源于https://goessner.net/articles/JsonPath/,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
}
}
}
解析情況如下:
XPath | JsonPath | Result |
/store/book/author | $.store.book[*].author | 所有book的author節(jié)點(diǎn) |
//author | $..author | 所有author節(jié)點(diǎn) |
/store/* | $.store.* | store下的所有節(jié)點(diǎn),book數(shù)組和bicycle節(jié)點(diǎn) |
/store//price | $.store..price | store下的所有price節(jié)點(diǎn) |
//book[3] | $..book[2] | 匹配第3個(gè)book節(jié)點(diǎn) |
//book[last()] | $..book[(@.length-1)],或 $..book[-1:] | 匹配倒數(shù)第1個(gè)book節(jié)點(diǎn) |
//book[position()<3] | $..book[0,1],或 $..book[:2] | 匹配前兩個(gè)book節(jié)點(diǎn) |
//book[isbn] | $..book[?(@.isbn)] | 過濾含isbn字段的節(jié)點(diǎn) |
//book[price<10] | $..book[?(@.price<10)] | 過濾price<10的節(jié)點(diǎn) |
//* | $..* | 遞歸匹配所有子節(jié)點(diǎn) |
可以在http://jsonpath.com/站點(diǎn)進(jìn)行驗(yàn)證JsonPath的執(zhí)行效果。
java中使用
pom中引用
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.4.0</version>
</dependency>
通常是直接使用靜態(tài)方法API進(jìn)行調(diào)用,例如:
String json = "...";
List<String> authors = JsonPath.read(json, "$.store.book[*].author");
但以上方式僅僅適用于解析一次json的情況,如果需要對同一個(gè)json解析多次,不建議使用,因?yàn)槊看蝦ead都會重新解析一次json,針對此種情況,建議使用ReadContext、WriteContext,例如:
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);