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.…

目标检测—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…

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

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

Thrift协议详解

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

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

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

uart控制led与beep

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

短视频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…

<蓝桥杯软件赛>零基础备赛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;同时支持水果蔬菜生鲜产品的在线销售。该系统整合了用户管理、产品管理、购物车、订单管理等核心功能&…

Python uiautomation获取微信内容!聊天记录、聊天列表、全都可获取

Python uiautomation 是一个用于自动化 GUI 测试和操作的库&#xff0c;它可以模拟用户操作来执行各种任务。 通过这个库&#xff0c;可以使用Python脚本模拟人工点击&#xff0c;人工操作界面。本文使用 Python uiautomation 进行微信电脑版的操作。 以下是本次实验的版本号。…

【C++】【Opencv】cv::warpAffine()仿射变换函数详解,实现平移、缩放和旋转等功能

仿射变换是一种二维变换&#xff0c;它可以将一个二维图形映射到另一个二维图形上&#xff0c;保持了图形的“形状”和“大小”不变&#xff0c;但可能会改变图形的方向和位置。仿射变换可以用一个线性变换矩阵来表示&#xff0c;该矩阵包含了六个参数&#xff0c;可以进行平移…

OpenCV技术应用(3)— 把.png图像保存为.jpg图像

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。本节课就手把手教你如何把.png图像保存为.jpg图像&#xff0c;希望大家学习之后能够有所收获~&#xff01;&#x1f308; 目录 &#x1f680;1.技术介绍 &#x1f680;2.实现代码 &#x1f680;1.技术介绍 如果在电脑某…

【SQL server】 表结构的约束和维护

表结构的约束和维护 修改表结构 (1)添加列 (2)删除列 (3)修改列alter table 表名 add 新列名 数据类型给员工表添加一列邮箱 alter table People add PeopleMail varchar(200)删除列 alter table People drop column PeopleMain修改列 alter table 表名 alter column 列名 数据…

【vue实战项目】通用管理系统:首页

前言 本文为博主的vue实战小项目系列中的第三篇&#xff0c;很适合后端或者才入门的小伙伴看&#xff0c;一个前端项目从0到1的保姆级教学。前面的内容&#xff1a; 【vue实战项目】通用管理系统&#xff1a;登录页-CSDN博客 【vue实战项目】通用管理系统&#xff1a;封装to…

学习css过渡动画-transition

文章目录 前言transition属性语法宽度改变效果透明度改变效果位置改变效果如有启发&#xff0c;可点赞收藏哟~ 前言 通常&#xff0c;当一个元素的样式属性值发生变化时&#xff0c;会立即看到页面发生变化。 css属性transition能让页面元素不是立即的、而是慢慢的从一种状态变…

Flink1.17 DataStream API

目录 一.执行环境&#xff08;Execution Environment&#xff09; 1.1 创建执行环境 1.2 执行模式 1.3 触发程序执行 二.源算子&#xff08;Source&#xff09; 2.1 从集合中读取数据 2.2 从文件读取数据 2.3 从 RabbitMQ 中读取数据 2.4 从数据生成器读取数据 2.5 …