在 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}]