介绍


JsonPath是一种能够提取部分JSON文档属性、对象、数组的语法,支持条件过滤、数学运算、字符串处理等功能。JsonPath与JSON文档就像 XPath 表达式与 XML 文档结合使用一样。

由于 JSON 结构通常是匿名的,并不一定和XML一样具有“根成员对象”,因此 JsonPath假定分配$给外层对象的抽象名称。JsonPath由用点分隔的表达式段(操作符)组成。 操作符可以是一个简单的词,如 JSON 值名称、*,也可以是括在方括号 [ ] 中的更复杂的构造。 括号段前的分隔点是可选的,也可以省略。下面是几种JsonPath的提取JSON文档内容语法:

JsonPath 描述
$.object.name 返回object.name的内容。
$.object['name'] 返回object.name的内容。
$.object.['name'] 返回object.name的内容。
$.object.history.length() 返回object.history数组元素的个数。
$[?(@.name == 'Object')].price.first() 返回第一个名为'Object'的对象的价格字段。
$[?(@.price > 10)].length() 返回price大于10的对象个数。

Jayway JsonPathStefan Goessner JsonPath的Java实现,是用于读取JSON文档的Java DSL。本文主要通过Jayway JsonPath来简单介绍JsonPath的使用语法,通过真实报文案例来进行操作。

支持的操作符


操作符 描述
` 操作符
--- ---
查询的根节点对象,表示一个json的数据,可以是对象或数组
@ 当前节点对象
* 通配符,获取所有节点
.. 递归查找,查找所有层次的属性值
<name> 按名称匹配对象属性。
.<name> 按照名称查找子节点
['<name>','<name>',...] 可用查找多个节点
[<number>,<number>,...] 按索引匹配数组元素,可同时查找多个数组元素
[start:end] 按定义的范围匹配数组元素:

<start>- 要匹配的第一个索引(包括)。 如果未指定,则匹配从头开始的所有数组元素。 如果为负数,则指定从数组末尾开始的偏移量。

<end>- 要匹配的最后一个索引(不包括)。 如果未指定,则匹配所有数组元素到最后。 如果为负数,则指定从数组末尾开始的偏移量。 | | [?(<expression>)] | 过滤表达式可匹配对象/数组元素,表达式的结果必须为布尔值 |

可以通过在 JSONPath 中添加 ~ 后缀来提取匹配的元素名称。 它返回匹配对象的名称或匹配数组项的字符串格式的索引。

过滤操作符


操作符 描述
== 等于
!= 不等于
< 小于
<= 小于或等于
> 大于
>= 大于或等于
=~ 匹配正则表达式 [?(@.name =~ /foo.*?/i)]
in 包含 [?(@.size in ['S', 'M'])]
nin 不包含
subsetof 子集 [?(@.sizes subsetof ['S', 'M', 'L'])]
anyof 交集 [?(@.sizes anyof ['M', 'L'])]
noneof 不是交集 [?(@.sizes noneof ['M', 'L'])]
size 左侧(数组或字符串)的大小应与右侧匹配
empty 左侧(数组或字符串)应该为空

支持的函数


可以在JsonPath表达式执行后进行调用,其输入值为表达式的结果。函数的输出看具体某个函数的含义。

函数 描述 返回值类型
min() 数值类型数组最小值 Double
max() 数值类型数组最大值 Double
avg() 数值类型数组平均值 Double
stddev() 数值类型数组标准差 Double
length() 数组长度 Integer
sum() 数值类型数组求和 Double
keys() 提取匹配的元素名称与~操作符功能一致 Set<E>
concat(X) 拼接 与入参相同
append(X) 把元素添加到JsonPath输出的数组中 与入参相同
first() 数组中的第一个元素 数组中元素类型
last() 数组中的最后一个元素 数组中元素类型
index(X) 提供索引为X的数组的元素,如果X为负数,则从后往前取 数组中元素类型

用一个复杂的接单报文来演示


https://jsonpath.com,这个在线网站可以用来验证JsonPath表达式,但是不支持函数,函数可以通过java代码来验证。

String json ="{.....}";
Object read = JsonPath.read(json, "$..price.min()");
System.out.println(read);

示例报文

{
"address":"大良街道同兴路****",
"createTime":"2023-09-20 17:48:44",
"customerName":"培^_^",
"id":0,
"memberId":"ECP002000*****",
"mobile":"184^_^8547",
"extendMessage":{
"clientNo":"testEBU516154",
"clientName":"广州网络科技有限公司",
"spSoNo":"test1976065878296",
"road":"011"
},
"odOrderDetailList":[
{
"id":1,
"productName":"白医生中频针灸理疗仪家用医院医用多功能颈椎肩周炎腰肌劳损电疗经络激光低频按摩器同款中频激光综合治疗仪 2023新款",
"quantity":1,
"productSku":"38fjjjj",
"price":189.6
},
{
"id":2,
"productName":"测试SKU",
"quantity":3,
"productSku":"ESG03JJ1",
"price":200
}
],
"totalPrice":0,
"volume":17318.4,
"extendInfo":{
"templateInfo":[
{
"code":"TP123",
"isPrint":1,
"type":2,
"printType":0
},
{
"code":"TPABC",
"isPrint":1,
"type":4,
"printType":0
}
],
"attrs":{
"plateFormCode":"274"
},
"senderName":"流苏",
"senderAddress":"广东省中山市南头镇永辉北路*****",
"paymentTime":"2023-09-20 17:22:31"
},
"carrierName":"京东配送",
"provinceName":"广东",
"isConsumable":0,
"merchantType":"0",
"tags":[
"a",
"b",
"c",
"d",
"e"
]
}

操作结果

JsonPath 结果
$.extendMessage.clientName "广州网络科技有限公司"
$.extendMessage['clientNo'] "testEBU516154"
$.extendMessage {"clientNo":"testEBU516154","clientName":"广州网络科技有限公司","spSoNo":"test1976065878296","road":"011"}
$.odOrderDetailList[0].productName "白医生中频针灸理疗仪家用医院医用多功能颈椎肩周炎腰肌劳损电疗经络激光低频按摩器同款中频激光综合治疗仪 2023新款"
$.odOrderDetailList[-1].productName "测试SKU"
$.odOrderDetailList.length() 2
$.tags[:] ["a", "b", "c", "d", "e" ]
$.tags[2:] ["c", "d", "e" ]
$.tags[:3] ["a", "b", "c"]
$.tags[1:4] ["b", "c", "d"]
$.tags[-2:] ["d", "e"]
$.tags[:-3] ["a", "b"]
$.tags[:-3].length() 2
$.odOrderDetailList[0,1].productName "白医生中频针灸理疗仪家用医院医用多功能颈椎肩周炎腰肌劳损电疗经络激光低频按摩器同款中频激光综合治疗仪 2023新款", "测试SKU"
$.odOrderDetailList[1].[productName,price] "测试SKU", 200
$..id 0,1,2
$.odOrderDetailList[?(@.id == 4 - 0.4 * 5)].productSku "ESG03JJ1"
$.odOrderDetailList[?(@.id == 1
$.extendInfo.templateInfo[?(!(@.type == 2))].code "TPABC"
$.extendInfo.templateInfo[?((@.type != 2))].code "TPABC"
$.odOrderDetailList[?(@.price > 190)].productName "测试SKU"
$.odOrderDetailList[?(@.id> $.id)].productSku ["38fjjjj","ESG03JJ1"]
$..[?(@.productSku)] [{"id":1,"productName":"白医生中频针灸理疗仪家用医院医用多功能颈椎肩周炎腰肌劳损电疗经络激光低频按摩器同款中频激光综合治疗仪 2023新款","quantity":1,"productSku":"38fjjjj","price":189.6},{"id":2,"productName":"测试SKU","quantity":3,"productSku":"ESG03JJ1","price":200}]
$..tags.length() 5
$.odOrderDetailList[*].price.min() 189.6
$..price.max() 200

作者:京东物流 马红岩

来源:京东云开发者社区 自猿其说 Tech 转载请注明来源

Jayway JsonPath-提取JSON文档内容的Java DSL的更多相关文章

  1. 不规范的json文档 转化成 java 对象的处理

    最近练习爬取数据,遇到了json文档中属性名称没有用双引号的情况,内容如下: 标准的json文档,属性名称都是带双引号的 最后写了个方法,替换属性名字 为 两头追加双引号的属性名字, 特别要注意,防止 ...

  2. 一个SQLServer中JSON文档型数据的查询问题

    近日在项目中遇到一个问题: 如何在报表中统计JSON格式存储的数据? 例如有个调查问卷记录表,记录每个问题的答案. 其结构示意如下(横表设计) Id user date Q1_Answer Q2_An ...

  3. java操作office和pdf文件java读取word,excel和pdf文档内容

    在平常应用程序中,对office和pdf文档进行读取数据是比较常见的功能,尤其在很多web应用程序中.所以今天我们就简单来看一下Java对word.excel.pdf文件的读取.本篇博客只是讲解简单应 ...

  4. C#提取TXT文档指定内容

    早上有分享一篇<VB.NET提取TXT文档指定内容> http://www.cnblogs.com/insus/p/3267347.html 那是原网友的需求用VB.NET写的.刚才有只懂 ...

  5. python、java、ruby、node等如何提取office文档中的内容?

    我相信大家都有过这样的需求,把doc.ppt.excel.pdf.txt中的文本内容提取出来.提取出来的文本内容可用于文档内容的全文索引,文档的基本内容摘要等.在度娘上搜索“如何提取文档内容”,确实有 ...

  6. Collection+JSON 文档

    Collection+JSON 文档 对于这个设计,我们不再以可能的状态和转移为起点,相反,我们将从一个集合状态响应中可能元素的顶层布局开始.从这一点入手,其他细节可以随着设计向超媒体类型最底层属性的 ...

  7. 使用DOM4J解析XML文档,以及使用XPath提取XML文档

    使用DOM4J解析XML文档 需要首先下载DOM4J工具包.这是个第三方工具包 在使用DOM4J解析的时候需要导入 DOM4J的JAR包 下载DOM4J工具包->在MyEclipse中新建lib ...

  8. 使用Java POI来选择提取Word文档中的表格信息

    通过使用Java POI来提取Word(1992)文档中的表格信息,其中POI支持不同的ms文档类型,在具体操作中需要注意.本文主要是通过POI来提取微软2003文档中的表格信息,具体code如下(事 ...

  9. QJsonDocument实现Qt下JSON文档读写

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QJsonDocument实现Qt下JSON文档读写     本文地址:http://tech ...

  10. package.json文档

    之前在博客中写过一篇关于 " node.js的安装配置 " 的文章,里面有提到利用 gulp watch 来监听文档的变化.其中需要 package.json 文件才能实现效果,所 ...

随机推荐

  1. [python]使用diagrams绘制架构图

    简介 diagrams是python的一个第三方库,用于实现使用代码绘制架构图. 安装 依赖于 Graphviz,安装diagrams之前需要先安装 Graphviz(下载压缩包后,将bin目录添加到 ...

  2. Java基础实现加油站圈存机系统

    加油站圈存机系统 ​ 对于加油卡而言,圈存是将用户账户中已存入的资金划转到所持的加油卡上后方可使用.通俗一点的说法就是您在网点把钱存入主卡中,再分配到下面的副卡,由于副卡都在使用车辆的驾驶员手中,需要 ...

  3. P1551 亲戚 && #569. 【例4-7】亲戚(并查集)

    P1551 亲戚 题目链接:落谷 题目链接:TFLS OJ 落谷题解(具体分析见慎入潜出P239) #include<bits/stdc++.h> using namespace std; ...

  4. 震坤行根据ID取商品详情 API

    item_get-根据ID取商品详情 注册开通 zhenkunhang.item_get 公共参数 名称 类型 必须 描述 key String 是 调用key(必须以GET方式拼接在URL中) se ...

  5. 入门篇-其之一-第一个Java程序

    ️注意: 本文中包含实际操作,需要安装JDK.如果需要安装JDK,请按照这篇文章的步骤进行安装:点我查看JDK安装教程 小白可以多看几遍这篇文章,多敲几次代码 前面我们已经安装了JDK,接下来就是写一 ...

  6. 详细解释一下Spring是如何解决循环依赖问题的

    Spring是如何解决循环依赖问题的? 我们都知道,如果在代码中,将两个或多个Bean互相之间持有对方的引用就会发生循环依赖.循环的依赖将会导致注入死循环,这是Spring发生循环依赖的原因 循环依赖 ...

  7. BZ全景编辑器(KRPano全景可视化编辑器, 无需编写代码, 图形化制作全景漫游)

    软件简介 BZ全景编辑器是一款KRPano全景可视化编辑工具,下载安装即可使用,无需拥有任何KRPano代码基础,便可以制作生成精美的全景漫游作品. BZ全景编辑器群:882083973 最新版软件下 ...

  8. day02 数据类型转换 运算符 方法

    数据类型转换 自动类型转换 强制类型转换 1. 自动类型转换:就是范围小的向范围大的转换  将取值范围小刀的类型自动提升为取值范围大的类型. 转换规则  byte.short.char  int--- ...

  9. 8.2 BeingDebugged

    BeingDebugged 是Windows系统PEB结构体中的一个成员,它是一个标志位,用于标识当前进程是否正在被调试.BeingDebugged的值为0表示当前进程未被调试,值为1表示当前进程正在 ...

  10. 解密Prompt系列16. LLM对齐经验之数据越少越好?LTD & LIMA & AlpaGasus

    LLM Agent中间插个队,总结下指令微调.对齐数据相关的方案,已经凑够7篇论文可以召唤神龙啦!论文都是以优化指令样本为核心,Data-Centric的观点比较一致:指令微调也就是对齐阶段的数据质量 ...