在 JsonPath 中创建过滤器谓词有三种不同的方法。
内联谓词是在 JsonPath 路径表达式中定义的谓词,例如:
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'))]
谓词可以使用过滤器 API 构建,如下所示:
package com.hxstrive.json_path;
import com.jayway.jsonpath.*;
import java.util.List;
import java.util.Map;
/**
* Jayway JsonPath 示例
* @author hxstrive.com
*/
public class Demo9 {
public static void main(String[] args) {
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" +
" }," +
" {" +
" \"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" +
"}";
Filter cheapFictionFilter = Filter.filter(
Criteria.where("category").is("fiction").and("price").lte(10D)
);
List<Map<String, Object>> books =
JsonPath.parse(json).read("$.store.book[?]", cheapFictionFilter);
System.out.println("books=" + books);
}
}
// 输出结果:
//books=[{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99}]注意:JsonPath 路径表达式中过滤器的占位符“?”,当提供多个过滤器时,它们将按顺序应用,其中占位符的数量必须与提供的过滤器数量相匹配。您可以在一个过滤器操作中指定多个谓词占位符[?, ?],但两个谓词必须匹配。
过滤器还可以与“OR”和“AND”组合使用,例如:
// OR 用法
Filter fooOrBar = filter(
where("foo").exists(true)).or(where("bar").exists(true)
);
// AND 用法
Filter fooAndBar = filter(
where("foo").exists(true)).and(where("bar").exists(true)
);我们一起看一个完整示例,代码代码如下:
package com.hxstrive.json_path;
import com.jayway.jsonpath.Criteria;
import com.jayway.jsonpath.Filter;
import com.jayway.jsonpath.JsonPath;
import java.util.List;
import java.util.Map;
/**
* Jayway JsonPath 示例
* @author hxstrive.com
*/
public class Demo10 {
public static void main(String[] args) {
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" +
" }," +
" {" +
" \"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" +
"}";
// and 的应用
Filter cheapFictionFilter = Filter.filter(
Criteria.where("category").is("fiction").and("price").lte(10D)
).or(Criteria.where("category").is("reference"));
// 使用过滤器
List<Map<String, Object>> books =
JsonPath.parse(json).read("$.store.book[?]", cheapFictionFilter);
System.out.println("books=" + books);
}
}
// 输出结果:
//books=[{"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}]第三种方法是实现自己的谓词,例如:
// 实现 Predicate 的 apply 方法
Predicate booksWithISBN = new Predicate() {
@Override
public boolean apply(PredicateContext ctx) {
return ctx.item(Map.class).containsKey("isbn");
}
};
// 应用自己的谓词
List<Map<String, Object>> books =
reader.read("$.store.book[?].isbn", List.class, booksWithISBN);我们来看一个完整示例:
package com.hxstrive.json_path;
import com.jayway.jsonpath.Criteria;
import com.jayway.jsonpath.Filter;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Predicate;
import java.util.List;
import java.util.Map;
/**
* Jayway JsonPath 示例
* @author hxstrive.com
*/
public class Demo11 {
public static void main(String[] args) {
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" +
" }," +
" {" +
" \"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" +
"}";
// 自定义谓词
Predicate booksWithISBN = new Predicate() {
@Override
public boolean apply(PredicateContext ctx) {
return ctx.item(Map.class).containsKey("isbn");
}
};
List<Map<String, Object>> books = JsonPath.read(json, "$.store.book[?]", booksWithISBN);
System.out.println(books);
}
}运行示例,输出结果:
books=[{"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}]