JsonPath:如何高效解析JSON并精准查找长尾词?

2026-04-11 05:192阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计894个文字,预计阅读时间需要4分钟。

JsonPath:如何高效解析JSON并精准查找长尾词?

项目特点:GitHub项目地址:https://github.com/json-path/JsonPath主要功能:将Json字符串转换为Java Map对象(这个不算什么,FastJson等工具类都可以做到)+ 通过强大的规则表达式定位字段,返回字段值

项目特点

GitHub项目地址:github.com/json-path/JsonPath
主要功能:

  1. 将Json字符串转为Java Map对象(这个不算什么,FastJson之类的工具都可以)
  2. 通过强大的规则表达式定位字段,返回字段值或值集合(很厉害)

支持的规则表达式以及示例(选自项目readme):

JsonPath (点击测试) 结果 $.store.book[*].author The authors of all books $..author All authors $.store.* All things, both books and bicycles $.store..price The price of everything $..book[2] The third book $..book[-2] The second to last book $..book[0,1] The first two books $..book[:2] All books from index 0 (inclusive) until index 2 (exclusive) $..book[1:2] All books from index 1 (inclusive) until index 2 (exclusive) $..book[-2:] Last two books $..book[2:] Book number two from tail $..book[?(@.isbn)] All books with an ISBN number $.store.book[?(@.price < 10)] All books in store cheaper than 10 $..book[?(@.price <= $['expensive'])] All books in store that are not "expensive" $..book[?(@.author =~ /.*REES/i)] All books matching regex (ignore case) $..* Give me every thing $..book.length() The number of books 实战测试

就用项目readme文档提供的例子进行测试:

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 }

POM中引入依赖:

JsonPath:如何高效解析JSON并精准查找长尾词?

<dependency> <groupId>com.jayway.jsonpath</groupId> <artifactId>json-path</artifactId> <version>2.7.0</version> </dependency>

写一个单元测试类:

@SpringBootTest @RunWith(MockitoJUnitRunner.class) public class JsonPathTest { private final String jsonStr = "..."; private final Object context = Configuration.defaultConfiguration().jsonProvider().parse(jsonStr); @Test public void test(){} }

其中:

  1. 第二个注解可以做到启动SpringBoot测试类而无需启动SpringApplication,并且也可以做到组件注入等功能。
  2. jsonStr用来指代之前所述的json字符串,这里简略写。
  3. context实际上是由json字符串通过默认配置生成的一个Map<String, Object>。

先看看context的类型:

System.out.println("context的类型:" + context.getClass().getSimpleName() + "\n"); ------------------------------------------------------------------ output: context的类型:LinkedHashMap

用法1:通过key定位一个value:

jsonpath = "$.store.book[1].price"; result = JsonPath.read(testMap, jsonpath); System.out.println("contents on " + jsonpath + ": " + result + "\n"); ------------------------------------------------------------------ output: contents on $.store.book[1].price: 12.99

用法2:通过key定位一组value:

jsonpath = "$.store.book[*].price"; result = JsonPath.read(context, jsonpath); System.out.println("contents on " + jsonpath + ": " + result + "\n"); ------------------------------------------------------------------ output: contents on $.store.book[*].price: [8.95,12.99,8.99,22.99]

这里如果去查看result的type,会发现它是JSONArray类型,是List<Object>接口的实现,当List用就可以了。

用法3:向下递归查找:

jsonpath = "$..price"; result = JsonPath.read(context, jsonpath); System.out.println("contents on " + jsonpath + ": " + result); ------------------------------------------------------------------ output: contents on $..price: [8.95,12.99,8.99,22.99,19.95]

在测试的时候想起一个问题,设想这样的场景,如果我们已经有了这样一个Map,只需要JsonPath提供的规则表达式解析与查找能力,那么想要使用JsonPath是不是需要Map->JsonString->context->规则解析->查找结果?答案是不需要的。
我们已经知道这个context本就是一个Map类型,那么是不是可以省去中间转为json string的步骤呢?我们测试看看:

//1. 先将json解析为一个Map Map<String, Object> testMap = (Map) JSONObject.parseObject(JSON_STRING); jsonpath = "$..price"; //2. 再将Map传入read方法,看是否能查找到结果: result = JsonPath.read(testMap, jsonpath); System.out.println("contents on " + jsonpath + ": " + result); ------------------------------------------------------------------ output: contents on $..price: [8.95,12.99,8.99,22.99,19.95]

可以看出,JsonPath的搜索规则解析能力是支持对普通Map进行查找的。

标签:规则解析

本文共计894个文字,预计阅读时间需要4分钟。

JsonPath:如何高效解析JSON并精准查找长尾词?

项目特点:GitHub项目地址:https://github.com/json-path/JsonPath主要功能:将Json字符串转换为Java Map对象(这个不算什么,FastJson等工具类都可以做到)+ 通过强大的规则表达式定位字段,返回字段值

项目特点

GitHub项目地址:github.com/json-path/JsonPath
主要功能:

  1. 将Json字符串转为Java Map对象(这个不算什么,FastJson之类的工具都可以)
  2. 通过强大的规则表达式定位字段,返回字段值或值集合(很厉害)

支持的规则表达式以及示例(选自项目readme):

JsonPath (点击测试) 结果 $.store.book[*].author The authors of all books $..author All authors $.store.* All things, both books and bicycles $.store..price The price of everything $..book[2] The third book $..book[-2] The second to last book $..book[0,1] The first two books $..book[:2] All books from index 0 (inclusive) until index 2 (exclusive) $..book[1:2] All books from index 1 (inclusive) until index 2 (exclusive) $..book[-2:] Last two books $..book[2:] Book number two from tail $..book[?(@.isbn)] All books with an ISBN number $.store.book[?(@.price < 10)] All books in store cheaper than 10 $..book[?(@.price <= $['expensive'])] All books in store that are not "expensive" $..book[?(@.author =~ /.*REES/i)] All books matching regex (ignore case) $..* Give me every thing $..book.length() The number of books 实战测试

就用项目readme文档提供的例子进行测试:

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 }

POM中引入依赖:

JsonPath:如何高效解析JSON并精准查找长尾词?

<dependency> <groupId>com.jayway.jsonpath</groupId> <artifactId>json-path</artifactId> <version>2.7.0</version> </dependency>

写一个单元测试类:

@SpringBootTest @RunWith(MockitoJUnitRunner.class) public class JsonPathTest { private final String jsonStr = "..."; private final Object context = Configuration.defaultConfiguration().jsonProvider().parse(jsonStr); @Test public void test(){} }

其中:

  1. 第二个注解可以做到启动SpringBoot测试类而无需启动SpringApplication,并且也可以做到组件注入等功能。
  2. jsonStr用来指代之前所述的json字符串,这里简略写。
  3. context实际上是由json字符串通过默认配置生成的一个Map<String, Object>。

先看看context的类型:

System.out.println("context的类型:" + context.getClass().getSimpleName() + "\n"); ------------------------------------------------------------------ output: context的类型:LinkedHashMap

用法1:通过key定位一个value:

jsonpath = "$.store.book[1].price"; result = JsonPath.read(testMap, jsonpath); System.out.println("contents on " + jsonpath + ": " + result + "\n"); ------------------------------------------------------------------ output: contents on $.store.book[1].price: 12.99

用法2:通过key定位一组value:

jsonpath = "$.store.book[*].price"; result = JsonPath.read(context, jsonpath); System.out.println("contents on " + jsonpath + ": " + result + "\n"); ------------------------------------------------------------------ output: contents on $.store.book[*].price: [8.95,12.99,8.99,22.99]

这里如果去查看result的type,会发现它是JSONArray类型,是List<Object>接口的实现,当List用就可以了。

用法3:向下递归查找:

jsonpath = "$..price"; result = JsonPath.read(context, jsonpath); System.out.println("contents on " + jsonpath + ": " + result); ------------------------------------------------------------------ output: contents on $..price: [8.95,12.99,8.99,22.99,19.95]

在测试的时候想起一个问题,设想这样的场景,如果我们已经有了这样一个Map,只需要JsonPath提供的规则表达式解析与查找能力,那么想要使用JsonPath是不是需要Map->JsonString->context->规则解析->查找结果?答案是不需要的。
我们已经知道这个context本就是一个Map类型,那么是不是可以省去中间转为json string的步骤呢?我们测试看看:

//1. 先将json解析为一个Map Map<String, Object> testMap = (Map) JSONObject.parseObject(JSON_STRING); jsonpath = "$..price"; //2. 再将Map传入read方法,看是否能查找到结果: result = JsonPath.read(testMap, jsonpath); System.out.println("contents on " + jsonpath + ": " + result); ------------------------------------------------------------------ output: contents on $..price: [8.95,12.99,8.99,22.99,19.95]

可以看出,JsonPath的搜索规则解析能力是支持对普通Map进行查找的。

标签:规则解析