继 Gson、Jackson、FastJson 之后基于JsonPath解析JSON

继 Gson、Jackson、FastJson 之后基于JsonPath解析JSON,第1张

基于JsonPath解析JSON
    • 一、JsonPath 说明
    • 二、JsonPath 语法
      • 1. 常用 *** 作符
      • 2. 常用过滤器 *** 作符
      • 3. 常用函数
    • 三、Java 语言实现JsonPath示例
      • 1. 引入 maven 坐标
      • 2. 数据准备
      • 3. json解析示例
    • 四、JsonPath 其他功能

一、JsonPath 说明

JsonPath是一种用于读取JSON文档的JavaDSL,能够方便快捷的解析复杂逻辑的Json。GitHub:JsonPath ,当然也可以 在线使用。

二、JsonPath 语法 1. 常用 *** 作符
OperatorDescription
$要查询的根元素。表示所有表达式的开始路径
@用在筛选器,表示当前节点
*作为通配符,匹配所有成员
..子递归通配符,匹配成员的所有子元素
..孩子节点名称
['' (, '')]括号中标注的一个或多个孩子节点
[ (, )]括号中标注一个或多个孩子节点的下标(索引),从0开始
[start:end]表示从start下标开始到 end下标结束(不包括 end 下标)孩子节点
[?()]过滤表达式。表达式的计算结果必须为布尔值
2. 常用过滤器 *** 作符
OperatorDescription
==左侧等于右侧。但是 1 不等于 ‘1’
!=左侧不等于右侧
<左侧小于右侧
<=左侧小于等于右侧
>左侧大于右侧
>=左侧大于等于右侧
=~左侧正则匹配右侧
in左侧存在于右侧集合
nin左侧不存在于右侧集合
size左侧(数组或字符串)的大小应与右侧匹配
empty左侧(数组或字符串)应为空
subsetof左侧是右侧的子集。测试时发现无法调通
anyof左侧与右侧的交集。测试时发现无法调通
noneof左侧和右侧不相交的部分。测试时发现无法调通
3. 常用函数
FunctionDescriptionOutput type
min()返回数组的最小值Double
max()返回数组的最大值Double
avg()返回数组的平均值Double
stddev()返回数组的标准方差Double
length()返回数组的长度Integer
sum()返回数组的总和Double
keys()没搞明白这个函数是做什么的Set
concat(X)将数组中元素拼接成一个新的元素like input
append(X)在 json 上添加元素。测试发现没有作用,提示没有该函数like input
三、Java 语言实现JsonPath示例 1. 引入 maven 坐标

    com.jayway.jsonpath
    json-path
    2.7.0

2. 数据准备

添加json文件 /json/ExampleJson.json ,内容如下所示:

{
  "store": [
    {
      "name": "京东",
      "label": "like",
      "book": [
        {
          "category": "Java",
          "author": "凯·S·霍斯特曼",
          "title": "Java核心技术",
          "price": 149,
          "nation": "M"
        },
        {
          "category": "Java",
          "author": "Bruce Eckel",
          "title": "Java编程思想",
          "price": 54.13,
          "nation": "M"
        },
        {
          "category": "Java",
          "author": "方腾飞",
          "title": "Java并发编程的艺术",
          "price": 48.12,
          "nation": "C"
        },
        {
          "category": "C++",
          "author": "安东尼威廉姆斯",
          "title": "C++并发编程实战",
          "price": 137.00,
          "nation": "M"
        },
        {
          "category": "",
          "author": "未知",
          "title": "测试",
          "price": 0,
          "nation": "C"
        }
      ],
      "bicycle": {
        "color": "red",
        "price": 1999.99
      },
      "avg": 60
    },
    {
      "name": "天猫",
      "book": [
        {
          "category": "Python",
          "author": "埃里克·马瑟斯 ",
          "title": "Python从入门到实践",
          "price": 107,
          "nation": "M"
        },
        {
          "category": "Python",
          "author": "明日科技",
          "title": "Python从入门到精通",
          "price": 36.80,
          "nation": "C"
        }
      ]
    }
  ],
  "from": "互联网"
}
3. json解析示例
package com.study;


import com.jayway.jsonpath.JsonPath;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;

/**
 * @author ouyangrongtao
 * @since 2022-04-20 22:28
 */
class JsonPathExampleTest {

    private InputStream resource;
    private static final Logger LOGGER = LoggerFactory.getLogger(JsonPathExampleTest.class);

    @BeforeEach
    void setUp() {
        resource = JsonPathExample.class.getResourceAsStream("/json/ExampleJson.json");
    }

    @Test
    void getAllBookListList() throws IOException {
        Object books = JsonPath.read(resource, "$..book");
        LOGGER.info("获取全部 book 节点:{}", books);
        Assertions.assertNotNull(books);
    }

    @Test
    void getAllBookList() throws IOException {
        Object books = JsonPath.read(resource, "$..book[*]");
        LOGGER.info("获取全部 book 节点:{}", books);
        Assertions.assertNotNull(books);
    }

    @Test
    void getAllAuthors() throws IOException {
        Object authors = JsonPath.read(resource, "$..author");
        LOGGER.info("获取全部 book 的 author:{}", authors);
        Assertions.assertNotNull(authors);
    }

    @Test
    void getJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0]");
        LOGGER.info("获取京东store:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getBicycleFromJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0].bicycle");
        LOGGER.info("获取京东 store 下的 bicycle:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getFirstBookFromJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0].book[0]");
        LOGGER.info("获取京东 store 下的第一的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getLastBookFromJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0].book[-1]");
        LOGGER.info("获取京东 store 下的最后的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getFirstBookOfAuthorFromJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0].book[0]['author', 'title']");
        LOGGER.info("获取京东 store 下的第一的 book 的 author 和 title:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getFirstAndThirdBookOfAuthorFromJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0].book[0, 2]");
        LOGGER.info("获取京东 store 下的第一和第三的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getFirstToThirdBookOfAuthorFromJingdong() throws IOException {
        Object o = JsonPath.read(resource, "$.store[0].book[0:3]");
        LOGGER.info("获取京东 store 下的第一到第三的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getExistLabel() throws IOException {
        Object o = JsonPath.read(resource, "$.store[?(@.label)]");
        LOGGER.info("获取 store 下存在 label 的 store:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getNameEqual() throws IOException {
        Object o = JsonPath.read(resource, "$.store[?(@.name=='京东')]");
        LOGGER.info("获取 name=京东 的 store:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getPriceGT100() throws IOException {
        Object o = JsonPath.read(resource, "$..book[?(@.price > 100)]");
        LOGGER.info("获取 price 大于 100 的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getPriceGTAvg() throws IOException {
        Object o = JsonPath.read(resource, "$..book[?(@.price > $.store[0].avg)]");
        LOGGER.info("获取 price 大于 avg 的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getCategoryEmpty() throws IOException {
        Object o = JsonPath.read(resource, "$..book[?(@.category == '')]");
        LOGGER.info("获取 Java 和 Python 的 book:{}", o);
        Assertions.assertNotNull(o);
    }

    @Test
    void getJavaAndPython() throws IOException {
        Object o = JsonPath.read(resource, "$..book[?(@.category in ['Java', 'Python'])]");
        LOGGER.info("获取 Java 和 Python 的 book:{}", o);
        Assertions.assertNotNull(o);
    }
    
    @Test
    void getMaxPrice() throws IOException {
        Object o = JsonPath.read(resource, "max($..book[?(@.price)].price)");
        LOGGER.info("获取 book 中最高的 price:{}", o);
        Assertions.assertNotNull(o);
    }
    
    @Test
    void getConcatPrice1() throws IOException {
        Object o = JsonPath.read(resource, "concat($..book[?(@.price)].price)");
        LOGGER.info("获取 book 中的price并拼接起来:{}", o);
        Assertions.assertEquals(o, "14954.1348.12137.0010736.8");
    }

    @Test
    void getConcatPrice2() throws IOException {
        Object o = JsonPath.read(resource, "$..book[?(@.price)].price.concat()");
        LOGGER.info("获取 book 中的price并拼接起来:{}", o);
        Assertions.assertEquals(o, "14954.1348.12137.0010736.8");
    }
}
四、JsonPath 其他功能
  1. 设置指定路径的json值

    @Test
    void setValue() {
        String newJson = JsonPath.parse(resource).set("$.from", "oy").jsonString();
        LOGGER.info("设置后的新json:{}", newJson);
        Assertions.assertNotNull(newJson);
    }
    

    注意: 设置值的 path 必须存在,否则报 PathNotFoundException 异常。

  2. 支持缓存,支持自定义
    com.jayway.jsonpath.spi.cache.LRUCache (default, thread safe)
    com.jayway.jsonpath.spi.cache.NOOPCache (no cache)
    自定义缓存使用 CacheProvider.setCache()

  3. JsonProvider SPI
    JsonSmartJsonProvider (default)
    JacksonJsonProvider
    JacksonJsonNodeJsonProvider
    GsonJsonProvider
    JsonOrgJsonProvider
    JakartaJsonProvider

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/720110.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-25
下一篇 2022-04-25

发表评论

登录后才能评论

评论列表(0条)

保存