JSONPath - 用于JSON的XPath
用来解析多层嵌套的json数据;JsonPath 是一种信息抽取类库,是从JSON文档中抽取指定信息的工具.
JsonPath有许多编程语言,如Javascript、Python、PHP、Java等
JsonPath提供的json解析非常强大,它提供了类似正则表达式的语法,基本上可以满足所有你想要获得的json内容。
JsonPath表达式始终引用JSON结构,其方式与XPath表达式与XML文档结合使用的方式相同。
$
无论是对象还是数组,JsonPath中的“根成员对象”始终被称为。JsonPath表达式可以使用点表示法
$.store.book[0].title
或括号表示法
$['store']['book'][0]['title']
com.jayway.jsonpath json-path 2.4.0 版本是个坑。。。。。。。。。。。。
Xpath | JSONPath | 描述 |
---|---|---|
/ | $ | 跟节点 |
. | @ | 现行节点 |
/ | . or [] | 取子节点 |
.. | n/a | 就是不管位置,选择所有符合条件的条件 |
* | * | 匹配所有元素节点 |
[] | [] | 迭代器标示(可以在里面做简单的迭代操作,如数组下标,根据内容选值等) |
| | [,] | 支持迭代器中做多选 |
[] | ?() | 支持过滤操作 |
n/a | () | 支持表达式计算 |
() | n/a | 分组,JsonPath不支持 |
{ "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
}
}
}
JsonPath.read() 获取到的返回值都是 list,除了 获取 size() 之外。这点注意一下。
注意,这里 必须要使用[*],此代表获取所有,在json中精确查找用这种比较好。
List titless = JsonPath.read(json, "$.store.book[*].title");
System.out.println("$.store.book.title \n " + titless);
结果:
$.store.book.title
["Sayings of the Century","Sword of Honour","Moby Dick","The Lord of the Rings"]
List title = JsonPath.read(json, "$..title");
System.out.println("$..title \n" + title);
结果:
$..title
["Sayings of the Century","Sword of Honour","Moby Dick","The Lord of the Rings"]
List isbn = JsonPath.read(json, "$.store.book[?(@.isbn)]");
System.out.println("$.store.book[?(@.isbn)] \n" + isbn);
结果:
$.store.book[?(@.isbn)]
[{"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}]
isbn = JsonPath.read(json, "$.store.book[?([email protected])]");
System.out.println("$.store.book[?([email protected])] \n" + isbn);
结果:
$.store.book[?([email protected])]
[{"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}]
Book.java
/**
* @author wbw
* @date 2019/7/18 9:56
*/
public class Book {
private String category;
private String author;
private String title;
private String price;
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"category='" + category + '\'' +
", author='" + author + '\'' +
", title='" + title + '\'' +
", price='" + price + '\'' +
'}';
}
}
JsonTest.java
import com.jayway.jsonpath.JsonPath;
import java.util.List;
/**
* @author wbw
* @date 2019/7/18 9:55
*/
public class JsonTest {
private static String json = "{ \"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" +
"}";
public static void main(String[] args) {
// 获取json中store下book下的所有title值
List titless = JsonPath.read(json, "$.store.book[*].title");
System.out.println("$.store.book.title \n " + titless);
System.out.println();
// 获取json中所有title的值
List title = JsonPath.read(json, "$..title");
System.out.println("$..title \n" + title);
System.out.println();
// 获取json中book数组中包含isbn的所有值
List isbn = JsonPath.read(json, "$.store.book[?(@.isbn)]");
System.out.println("$.store.book[?(@.isbn)] \n" + isbn);
System.out.println();
// 获取json中book数组中不包含isbn的所有值
isbn = JsonPath.read(json, "$.store.book[?([email protected])]");
System.out.println("$.store.book[?([email protected])] \n" + isbn);
System.out.println();
// 获取json中book数组中price<10的所有值
List prices = JsonPath.read(json, "$.store.book[?(@.price < 10)].price");
System.out.println("$.store.book[?(@.price < 10)].price \n" + prices);
System.out.println();
// 获取json中book数组中的title等于“高效Java”的对象
List titles = JsonPath.read(json, "$.store.book[?(@.title == 'The Lord of the Rings')]");
System.out.println("$.store.book[?(@.title == 'The Lord of the Rings')] \n" + titles);
System.out.println();
// 获取json中store下所有price的值
prices = JsonPath.read(json, "$..price");
System.out.println("$..price \n" + prices);
System.out.println();
// 获取json中book数组的前两个区间值
List book = JsonPath.read(json, "$.store.book[0:4]");
System.out.println("$.store.book[2:4] \n" + book);
System.out.println();
// 获取书个数
int size = JsonPath.read(json, "$.store.book.size()");
System.out.println("$.store.book.size() \n" + size);
System.out.println();
// 获取store中bicycle的颜色
List color = JsonPath.read(json, "$.store..color");
System.out.println("$.store..color \n" + color.get(0));
}
}
jsonpath 确实是个好用的东西,表达式的过滤,极大方便了json数据的处理。值使用时候,需要注意json的格式, .. 和 [] 不宜乱用。索引的使用,比如[0,1]只获取第0位的数据,而 第 1 为的数据是不包含的。
版本是个坑。