JsonPath详细使用教程,你了解多少?
Json Path介绍看它的名字你就能知道,这Json Path和JSON文档有关系,正如XPath之于XML文档一样,JsonPath为Json文档提供了解析能力,通过使用JsonPath,你可以方便的查找节点、获取想要的数据,JsonPath是Json版的XPath 。
JsonPath语法
- $ 表示文档的根元素
- @ 表示文档的当前元素
- .node_name 或 ['node_name'] 匹配下级节点
- [index] 检索数组中的元素
- [start:end:step] 支持数组切片语法
- * 作为通配符,匹配所有成员
- .. 子递归通配符,匹配成员的所有子元素
- (<expr>) 使用表达式
- ?(<boolean expr>)进行数据筛选
JsonPath
说明
/
$
文档根元素
.
@
当前元素
/
.或[]
匹配下级元素
..
N/A
匹配上级元素,JsonPath不支持此操作符
//
..
递归匹配所有子元素
*
*
通配符,匹配下级元素
@
N/A
匹配属性,JsonPath不支持此操作符
[]
[]
下标运算符,根据索引获取元素,XPath索引从1开始,JsonPath索引从0开始
`
`
[,]
N/A
[start:end:step]
数据切片操作,XPath不支持
[]
?()
过滤表达式
N/A
()
脚本表达式,使用底层脚本引擎,XPath不支持
()
N/A
分组,JsonPath不支持
示例下面是相应的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节点
//author
$..author
所有author节点
/store/*
$.store.*
store下的所有节点,book数组和bicycle节点
/store//price
$.store..price
store下的所有price节点
//book[3]
$..book[2]
匹配第3个book节点
//book[last()]
$..book[(@.length-1)],或 $..book[-1:]
匹配倒数第1个book节点
//book[position()<3]
$..book[0,1],或 $..book[:2]
匹配前两个book节点
//book[isbn]
$..book[?(@.isbn)]
过滤含isbn字段的节点
//book[price<10]
$..book[?(@.price<10)]
过滤price<10的节点
//*
$..*
递归匹配所有子节点
可以在http://jsonpath.com/站点进行验证JsonPath的执行效果 。
JAVA中使用pom中引用
<dependency><groupId>com.jayway.jsonpath</groupId><artifactId>json-path</artifactId><version>2.4.0</version></dependency>
通常是直接使用静态方法API进行调用,例如:String json = "...";List<String> authors = JsonPath.read(json, "$.store.book[*].author");
但以上方式仅仅适用于解析一次json的情况,如果需要对同一个json解析多次,不建议使用,因为每次read都会重新解析一次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);