JsonPath 谓词(Predicates)

在 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}]
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号