Java中如何通过路径表达式找值:XPath和JsonPath以及SpEL详解及对比

大家好,我是G探险者。

我们编程时,在前后端数据交互和传输过程中,往往需要对报文中的某个字段或者某个标签的值进行解析读取,报文通常是以json或者xml作为数据交换格式,而json和xml这两种格式的报文结构都是具备一定的层级关系的,也就是说我们要想要拿到报文里面的某个值,是可以通过一个路径定位到的,那么它们具体是怎么通过路径定位到具体的值呢?

今天咱们就来聊一聊XPath和JsonPath.

1. XPath

XPath,即XML路径语言,是一种用于在XML文档中查找信息的语言。它使用路径表达式来选取XML文档中的节点或节点集。这些路径表达式看起来很像文件系统中的路径,旨在快速地定位和操作文档中的元素。

特点

  • 数据格式: 专用于XML。
  • 查询结构/root/child/grandchild的形式,非常结构化。
  • 表达式能力: 支持逻辑运算、算术运算和内置函数。
  • 使用场景: 主要用于XML文档的导航和查询。

示例代码

假设有以下XML报文:

<books><book><title>Java Programming</title><author>James Gosling</author></book><book><title>XML Fundamentals</title><author>John Doe</author></book>
</books>

使用XPath找到所有书籍的标题:

// 导入所需的XML处理库
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathConstants;
import org.w3c.dom.NodeList;// ...// 创建DocumentBuilderFactory实例以解析XML文档
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 创建DocumentBuilder实例
DocumentBuilder builder = factory.newDocumentBuilder();
// 解析XML文档,这里假设文件名为books.xml
Document doc = builder.parse("books.xml");
// 创建XPath实例来查询XML文档
XPath xpath = XPathFactory.newInstance().newXPath();
// XPath表达式,用来选择所有的<title>元素
String expression = "/books/book/title";
// 执行XPath查询并获取结果节点列表
NodeList titles = (NodeList) xpath.evaluate(expression, doc, XPathConstants.NODESET);// 遍历结果节点列表并打印每个<title>元素的文本内容
for (int i = 0; i < titles.getLength(); i++) {System.out.println(titles.item(i).getTextContent());
}

2. JsonPath

JsonPath是从XPath中发展而来的,专门用于JSON数据格式。它提供了一种简单的方法来使用类似XPath的语法,从JSON对象中提取所需的信息。

特点

  • 数据格式: 专用于JSON。
  • 查询结构: 使用点记法(例如$.object.property)或数组记法(例如$['object']['property'])。
  • 表达式能力: 简单,主要用于定位和过滤数据。
  • 使用场景: 处理RESTful服务返回的JSON数据,以及其他JSON数据处理。

示例代码

假设有如下JSON报文:

{"store": {"book": [{ "title": "Clean Code", "author": "Robert C. Martin" },{ "title": "The Pragmatic Programmer", "author": "Andrew Hunt and David Thomas" }],"bicycle": {"color": "red","price": 19.95}}
}

使用JsonPath获取所有书籍的标题:

首先需要引入这个依赖:

<dependency><groupId>com.jayway.jsonpath</groupId><artifactId>json-path</artifactId><version>2.8.0</version>
</dependency>
// 导入JsonPath库
import com.jayway.jsonpath.JsonPath;
import net.minidev.json.JSONArray;// ...// JSON字符串,表示一个书店的存货,包括书籍和自行车
String json = "{ \"store\": { \"book\": [ { \"title\": \"Clean Code\", \"author\": \"Robert C. Martin\" }, { \"title\": \"The Pragmatic Programmer\", \"author\": \"Andrew Hunt and David Thomas\" } ], \"bicycle\": { \"color\": \"red\", \"price\": 19.95 } } }";
// JsonPath表达式,用来选取所有书籍的标题
String jsonPathExpression = "$.store.book[*].title";// 执行JsonPath查询并获取结果为JSONArray
JSONArray bookTitles = JsonPath.read(json, jsonPathExpression);// 遍历JSONArray并打印每本书的标题
for (Object title : bookTitles) {System.out.println(title);
}

除了上面这个com.jayway.jsonpath 依赖包的方法,还有另外一个依赖包可以处理,官网学习地址:https://github.com/noear/snack3

<dependency><groupId>org.noear</groupId><artifactId>snack3</artifactId>
</<dependency>

3. 拓展

除了以上的XPath和JsonPath,其实还有类似的路径表达式是来从对象中获取某个值
SpEL(Spring Expression Language)和EL(Expression Language)通常用于在Java企业应用中进行动态查询和管理应用程序的行为。
SpEL是Spring框架提供的一种功能强大的表达式语言,而EL最初是为了简化JSP页面的数据展示而生,后来也被整合到了JSF和其他Java企业技术中。

3.1 SpEL

  • 数据格式: 不依赖特定数据格式,可以用于对象图导航。
  • 查询结构: 使用类似于JsonPath的点记法,如@beanName.method()
  • 表达式能力: 非常强大,支持方法调用、关系运算、正则表达式匹配等。
  • 使用场景: 在Spring框架中进行配置、验证、模板操作等,非常灵活。

示例代码:

import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.Expression;// 创建一个表达式解析器
ExpressionParser parser = new SpelExpressionParser();// 解析一个字符串表达式,并执行字符串拼接
Expression exp = parser.parseExpression("'Hello World'.concat('!')");
String message = (String) exp.getValue();// 输出结果,将打印:Hello World!
System.out.println(message);

3.2 EL

  • 数据格式: 不依赖特定数据格式,通常用于访问JavaBeans对象。
  • 查询结构: 使用${object.property}的形式,主要用于Web层。
  • 表达式能力: 相对简单,支持简单的属性访问和算术操作。
  • 使用场景: 主要用于JSP和JSF等Java EE技术中,用于简化页面层的数据展示。
import javax.el.ELProcessor;// 创建ELProcessor实例
ELProcessor elProcessor = new ELProcessor();// 定义一个变量并赋值
elProcessor.setValue("greeting", "Hello");// 使用EL表达式拼接字符串
String result = (String) elProcessor.eval("greeting.concat(' World!')");// 输出结果,将打印:Hello World!
System.out.println(result);

4. 对比分析

特性XPathJsonPathSpELEL
数据格式XMLJSON任意任意
查询语法结构化路径点记法/数组记法点记法/方法调用简化属性访问
表达式能力逻辑/算术运算定位/过滤方法调用/正则表达式简单属性/算术
使用场景XML文档查询JSON数据处理Spring应用JSP/JSF页面

5. 总结

XPathJsonPath都是强大的查询语言,它们使得从复杂的数据结构中提取信息变得更加容易。XPath适用于XML数据,而JsonPath适用于JSON数据。两者各有优势,具体使用哪一个取决于你的数据格式和需求。在Java中,有多个库可以用来执行XPath和JsonPath查询,如javax.xml.xpathcom.jayway.jsonpath等。

在选择使用哪种表达式语言时,通常取决于你的应用场景和所操作的数据类型。如果你在处理XML或JSON数据,XPath和JsonPath是专门为这些格式设计的。而如果你在Spring框架中工作,SpEL将提供更丰富的功能和更大的灵活性。对于简单的Web页面数据展示,EL是一个轻量级且易于使用的选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/147490.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker容器自启动

场景 当服务器关机重启后&#xff0c;docker容器每次都要去docker start 容器id 怎么可以下次让它自启动呢&#xff1f; 解决 先 # docker ps -a 查到之前启动过的容器id # docker update --restartalways 容器id重启后&#xff0c;reboot&#xff0c;就不用再单独去启动容…

string类的总结

目录 1.为什么要学习string类 2.string的标准库 3.string类的常用接口说明 1.string类对象的常见构造 2.string类对象的容量操作 3.string类对象的3种遍历方法 3.1 [ ] 下标 3.2 基于范围的for循环 3.3 迭代器 4 string类对象的元素访问 4.1 operator[]&#xff1a; 4.…

【洛谷 P3853】[TJOI2007] 路标设置 题解(二分答案+循环)

[TJOI2007] 路标设置 题目背景 B 市和 T 市之间有一条长长的高速公路&#xff0c;这条公路的某些地方设有路标&#xff0c;但是大家都感觉路标设得太少了&#xff0c;相邻两个路标之间往往隔着相当长的一段距离。为了便于研究这个问题&#xff0c;我们把公路上相邻路标的最大…

目标检测—YOLO系列(二 ) 全面解读复现YOLOv1 PyTorch

精读论文 前言 从这篇开始&#xff0c;我们将进入YOLO的学习。YOLO是目前比较流行的目标检测算法&#xff0c;速度快且结构简单&#xff0c;其他的目标检测算法如RCNN系列&#xff0c;以后有时间的话再介绍。 本文主要介绍的是YOLOV1&#xff0c;这是由以Joseph Redmon为首的…

交通 | 神奇动物在哪里?Operations Research经典文章

论文作者&#xff1a;Robert G. Haight, Charles S. Revelle, Stephanie A. Snyder​ 论文原文&#xff1a;Robert G. Haight, Charles S. Revelle, Stephanie A. Snyder, (2000) An Integer Optimization Approach to a Probabilistic Reserve Site Selection Problem. Operat…

C语言比较运算符

常用比较运算符 常用的比较运算符有&#xff1a; ! < > < > 运算符术语示例表示结果相等于2 10!不等于2 ! 11<小于2 < 10>大于2 > 11<小等于2 < 10>大于等于2 > 11 比较运算符注意事项 C语言的比较运算中&#xff0c;真用数字 1 表示…

VR智慧景区:VR赋能文旅产业,激活消费潜能

随着国家数字化战略的不断深入实施&#xff0c;文旅产业数字化转型的步伐也在逐渐加快&#xff0c;以VR技术赋能文旅产业&#xff0c;让文旅景区线上线下双渠道融合&#xff0c;进一步呈现文化底蕴、激活消费潜能。 VR智慧景区以沉浸式、互动式、科技感的方式&#xff0c;将景区…

C语言编程陷阱(八)

陷阱36:不要使用指针作为函数的返回值 有时候,我们可能想要用一个函数来返回一个指针,比如返回一个动态分配的内存,或者返回一个数组的某个元素的地址。但是,如果我们不小心,我们可能会犯一个很常见的错误,就是返回一个局部变量的地址。例如,看看下面的代码: #inclu…

Thrift协议详解

前言特点高效性的体现可拓展性的体现 应用场景示例拓展其他常用协议接口描述语言&#xff08;IDL&#xff09;TBinaryProtocolTCompactProtocolTDebugProtocolTDenseProtocolTJSONProtocol 前言 Thrift协议是一种接口描述语言和二进制通讯协议&#xff0c;它被用来定义和创建跨…

基于STM32的多组外部中断(EXTI)的优化策略与应用

在某些嵌入式应用中&#xff0c;可能需要同时处理多个外部中断事件。STM32系列微控制器提供了多组外部中断线&#xff08;EXTI Line&#xff09;&#xff0c;可以同时配置和使用多个GPIO引脚作为外部中断触发器。为了有效管理和处理多组外部中断&#xff0c;我们可以采取一些优…

腾讯云轻量应用服务器使用场景列举说明

腾讯云轻量应用服务器&#xff08;TencentCloud Lighthouse&#xff09;是新一代开箱即用、面向轻量应用场景的云服务器产品&#xff0c;轻量应用服务器可用于搭建中小型网站、Web应用、博客、论坛、小程序/小游戏、电商、云盘/图床、云端开发测试和学习环境等轻量级、中低负载…

uart控制led与beep

仲裁模块代码&#xff1a; // 外设控制模块&#xff0c;根据uart接收到的数据&#xff0c;控制led与beep的标志信号。 module arbit(input wire sys_clk ,input wire sys_rst_n ,input wire pi_flag …

Nginx负载均衡机制及常见问题

介绍 Nginx是目前主流的WEB服务器发布软件&#xff0c;不仅可以作为强大的web服务器&#xff0c;也可以作为一个反向代理服务器&#xff0c;而且nginx还可以按照调度规则实现动静分离&#xff0c;可以按照轮询、ip_hash、URL哈希、权重等多种方式对后端服务器做负载均衡&#…

Qt实现将字节数组以hex形式显示到文本框的方法

0. 最简单的方法&#xff1a; QString hexString buf.toHex( ); ui->rx_textEdit->append(hexString); 1. 使用 toHex 和循环插入空格&#xff1a; - 优点&#xff1a; 这种方法使用了Qt提供的现成功能&#xff0c;更符合Qt的风格&#xff0c;而且代码相对简洁易懂…

短视频ai剪辑分发账号矩阵系统(招商oem)----源头技术开发

短视频ai剪辑分发账号矩阵系统 1. 视频剪辑工具——原创短视频一键生成&#xff0c;视频剪辑亮点分析 &#xff08;1&#xff09;多模式智能剪辑 包含智能混剪逻辑、智能组合、场景顺序、图片生成视频等多种模式。在视频创作上也做了简化&#xff0c;即使是没有剪辑能力的创…

Android resource/drawable转换成Uri,Kotlin

Android resource/drawable转换成Uri&#xff0c;Kotlin private fun convertResource2Uri(resId: Int): Uri {return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE "://" resources.getResourcePackageName(resId) / resources.getResourceTypeName(resI…

3-运行第一个docker image-hello world

CentOS7.9下安装完成docker后,我们开始部署第一个docker image-hello world 1.以root用户登录CentOS7.9服务器,拉取centos7 images 命令: docker pull hello-world [root@centos79 ~]# docker pull hello-world Using default tag: latest latest: Pulling from library…

<蓝桥杯软件赛>零基础备赛20周--第6周--数组和队列

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周&#xff08;读者可以按…

python django 小程序博客源码

开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索文章&#xff0c;文章分类&#xf…

基于django水果蔬菜生鲜销售系统

基于django水果蔬菜生鲜销售系统 摘要 基于Django的水果蔬菜生鲜销售系统是一种利用Django框架开发的电子商务平台&#xff0c;旨在提供高效、便捷的购物体验&#xff0c;同时支持水果蔬菜生鲜产品的在线销售。该系统整合了用户管理、产品管理、购物车、订单管理等核心功能&…