Java中的XML解析

article/2025/9/24 9:05:47

前言

这几天在手写Spring IOC的时候遇上了xml文件的解析,通过解析Spring.xml配制文件的方式来创建对象。因为之前从来都没遇见过相关的需求,所以对此做一份记录
XML (eXtensible Markup Language) 意为可扩展标记语言,被多数技术人员用以选择作为数据传输的载体,成为一种通用的数据交换格式,xml的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的便利。在不同的语言中,解析mxl的方式都是一样的,只不过实现的语法不同而已。
XML解析主要有两种方式,一种称为DOM解析,另外一种称之为SAX解析

  • DOM解析:Document Object Model,简单的来讲,DOM解析就是读取XML文件,然后在文件文档描述的内容在内存中生成整个文档树。
  • SAX解析:Simple API for XML,简单的来讲,SAX是基于事件驱动的流式解析模式,一边去读文件,一边解析文件,在解析的过程并不保存具体的文件内容。

这两种方式都是原生的解析方式,在编码的时候难免会有一些繁琐,所以我们经常会用到一些第三方的框架,目前主流的有:JDOM、StAX、XPath、DOM4j
为了方便后面的测试,先给出一份xml配制文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans><bean id="userDao" class="cuit.pymjl.entity.UserDao"/><bean id="userService" class="cuit.pymjl.entity.UserService"><property name="id" value="2"/><property name="userDao" ref="userDao"/></bean></beans>

Dom解析

  1. 概述

DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。

  • 优点:在内存中形成了整个文档树,有了文档树,就可以随便对文档中任意的节点进行操作(增加节点、删除节点、修改节点信息等),而且由于已经有了整个的文档树,可以实现对任意节点的随机访问。
  • 缺点:由于需要在内存中形成文档树,需要消耗的内存比较大,尤其是当文件比较大的时候,消耗的代价还是不容小视的。
  1. 代码示例
public class XmlReader {public static void main(String[] args) {parse();}public static void parse() {// Spring.xml的内容为上面所示XML代码内容File file = new File("C:\\Users\\Admin\\JavaProjects\\blog-code-demo\\xml-parse\\src\\main\\resources\\spring.xml");try {// 创建文档解析的对象DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder builder = factory.newDocumentBuilder();// 解析文档,形成文档树,也就是生成Document对象Document document = builder.parse(file);// 获得根节点Element rootElement = document.getDocumentElement();System.out.printf("Root Element: %s\n", rootElement.getNodeName());// 获得根节点下的所有子节点NodeList students = rootElement.getChildNodes();for (int i = 0; i < students.getLength(); i++) {// 获得第i个子节点Node childNode = students.item(i);// 由于节点多种类型,而一般我们需要处理的是元素节点// 元素节点就是非空的子节点,也就是还有孩子的子节点if (childNode.getNodeType() == Node.ELEMENT_NODE) {Element childElement = (Element) childNode;System.out.printf(" Element: %s\n", childElement.getNodeName());System.out.printf("  Attribute: id = %s\n", childElement.getAttribute("id"));System.out.printf("  Value: class= %s\n", childElement.getAttribute("class"));// 获得第二级子元素NodeList childNodes = childElement.getChildNodes();for (int j = 0; j < childNodes.getLength(); j++) {Node child = childNodes.item(j);if (child.getNodeType() == Node.ELEMENT_NODE) {Element eChild = (Element) child;String value = eChild.getAttribute("value");String ref = eChild.getAttribute("ref");if (value != null && value.length() > 0) {System.out.printf("  sub Element %s:  name= %s value= %s\n", eChild.getNodeName(),eChild.getAttribute("name"), value);} else {System.out.printf("  sub Element %s:  name= %s ref= %s\n", eChild.getNodeName(), eChild.getAttribute("name"),ref);}}}}}} catch (ParserConfigurationException | SAXException | IOException e) {e.printStackTrace();}}
}

因为我使用的原生的Dom解析,所以就不需要引入任何其他的依赖

  1. 运行结果:

image.png

SAX解析

  1. 概述

SAX处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。一般来说,SAX还比它的替代者DOM快许多。

  • 优点:SAX解析由于是一边读取文档一边解析的,所以所占用的内存相对来说比较小。
  • 缺点:无法保存文档的信息,无法实现随机访问节点,当文档需要编辑的时候,使用SAX解析就比较麻烦了。

SAX解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag.特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据

  1. 代码示例:
package cuit.pymjl;import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;/*** @author Pymjl* @version 1.0* @date 2022/7/4 13:01**/
public class SAXHandler extends DefaultHandler {@Overridepublic void startDocument() throws SAXException {System.out.println("====================Starting parse the document=======================");}@Overridepublic void endDocument() throws SAXException {System.out.println("=================Ending parse the document=======================");}@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {if (qName.equals("bean")) {System.out.println("Bean{id=" + attributes.getValue(0) +",class=" + attributes.getValue(1) + "}");} else if (qName.equals("property")) {System.out.println("Property{name=" + attributes.getValue(0) +",value=" + attributes.getValue(1) + "}");}}public static void parser() {try {File file = new File("C:\\Users\\Admin\\JavaProjects\\blog-code-demo\\xml-parse\\src\\main\\resources\\spring.xml");// 创建一个SAX解析器SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();javax.xml.parsers.SAXParser parser = saxParserFactory.newSAXParser();// 解析对应的文件parser.parse(file, new SAXHandler());} catch (ParserConfigurationException | SAXException | IOException e) {e.printStackTrace();}}public static void main(String[] args) {parser();}
}
  1. 运行截图

image.png

小结

好了,关于XML解析我就说在这里,我是直接参照的原生的方式写的xml解析,并没有使用第三方库,如果其他小伙伴对此感兴趣可以自行研究其他的框架
最后,贴上我在写Spring解析xml的代码(这里用到了Hutool的工具类,但是其实只是对原生的一个简单的封装)

   /*** 加载BeanDefinition的具体实现方法,对xml进行解析,并且将解析后的bean定义信息放入bean定义注册表中** @param inputStream 输入流* @throws ClassNotFoundException 类没有发现异常*/protected void doLoadBeanDefinitions(InputStream inputStream) throws ClassNotFoundException {// 1. 获取xml文档对象Document doc = XmlUtil.readXML(inputStream);// 2. xml文件的获取根节点Element root = doc.getDocumentElement();// 3. 获取根节点下的所有子节点NodeList childNodes = root.getChildNodes();// 4. 遍历所有子节点for (int i = 0; i < childNodes.getLength(); i++) {// 5.判断元素的类型,是否是元素节点if (!(childNodes.item(i) instanceof Element)) {continue;}// 6.判断对象if (!"bean".equals(childNodes.item(i).getNodeName())) {continue;}// 7.解析标签Element bean = (Element) childNodes.item(i);String id = bean.getAttribute("id");String name = bean.getAttribute("name");String className = bean.getAttribute("class");// 8.获取 Class,方便获取类中的名称Class<?> clazz = Class.forName(className);// 9.优先级 id > nameString beanName = StrUtil.isNotEmpty(id) ? id : name;if (StrUtil.isEmpty(beanName)) {beanName = StrUtil.lowerFirst(clazz.getSimpleName());}// 10.定义BeanBeanDefinition beanDefinition = new BeanDefinition(clazz);// 11.读取属性并填充for (int j = 0; j < bean.getChildNodes().getLength(); j++) {if (!(bean.getChildNodes().item(j) instanceof Element)) {continue;}if (!"property".equals(bean.getChildNodes().item(j).getNodeName())) {continue;}// 12.解析标签:propertyElement property = (Element) bean.getChildNodes().item(j);String attrName = property.getAttribute("name");String attrValue = property.getAttribute("value");String attrRef = property.getAttribute("ref");// 13.获取属性值:引入对象、值对象Object value = StrUtil.isNotEmpty(attrRef) ? new BeanReference(attrRef) : attrValue;// 14.创建属性信息PropertyValue propertyValue = new PropertyValue(attrName, value);beanDefinition.getPropertyValues().addPropertyValue(propertyValue);}if (getRegistry().containsBeanDefinition(beanName)) {throw new BeansException("Duplicate beanName[" + beanName + "] is not allowed");}// 15.注册 BeanDefinitiongetRegistry().registerBeanDefinition(beanName, beanDefinition);}

http://chatgpt.dhexx.cn/article/KEdPoboF.shtml

相关文章

Java - XML文件解析

Java对XML文件的解析 一、前言二、实例分析 - DOM方式解析XML文件2.1 XMLDomParseUtil - 抽象工具类2.2 待解析xml文件示例2.3 解析xml文件2.3.1 新建一个用于存储xml文件中各节点的属性和属性值的类2.3.2 解析实际节点 2.4 测试 一、前言 1、HTTP网络传输中的数据组织方式有三…

Java解析XML文件的方式

在项目里&#xff0c;我们往往会把一些配置信息放到xml文件里&#xff0c;或者各部门间会通过xml文件来交换业务数据&#xff0c;所以有时候我们会遇到“解析xml文件”的需求。一般来讲&#xff0c;有基于DOM树和SAX的两种解析xml文件的方式&#xff0c;在这部分里&#xff0c;…

java解析xml格式的节点属性值

xml示例&#xff1a; <ResponseContent><Parameter><Document><RecordSet id"1"><Master name"purchase"><Record><Field name"orderNumber" value"1P05-151200172"/><Field name"…

Java解析XML字符串

在网上找了很多Java语言解析XML字符串的资料&#xff0c;很多内容写得很繁复&#xff0c;没有普适性&#xff0c;遂自己动手写了一个用Java解析XML的工具类。话不多说&#xff0c;直接看下面代码&#xff1a; XML解析工具类&#xff1a; import org.dom4j.Document; import o…

JAVA解析xml报文

目录 问题需求 响应报文格式 1&#xff0c;开发导入的依赖 2&#xff0c;开发样例 3&#xff0c;测试结果 问题需求 在工作中此项目请求指定项目之后&#xff0c;项目会返回一个xml报文格式的响应&#xff0c;此时我需要判断返回的报文是否是成功的响应报文&#xff0c;如…

Java解析xml

记录工作中遇到的一些问题和解决方式&#xff0c;自己摘抄整理了一下用来巩固&#xff0c;如有不足或有更好的方式 欢迎交流。 java解析xml的话有四种方式&#xff0c;分别为DOM,SAX,DOM4J,JDOM 转载&#xff1a;Java解析XML(4种方法)_蓝星花的博客-CSDN博客_java解析xml 这里的…

Java解析XML(4种方法)

xml文件 <?xml version"1.0" encoding"utf-8" ?> <class><student><firstname>cxx1</firstname><lastname>Bob1</lastname><nickname>stars1</nickname><marks>85</marks></stud…

混合开发架构|Android工程集成React Native、Flutter、ReactJs

混合开发架构|Android工程集成React Native、Flutter、ReactJs 架构设计说明创建安卓原生工程创建Flutter集成嵌入原生工程 创建React Native解决RN报错问题集成嵌入原生工程RN集成后&#xff0c;启动报错 底部导航栏架构设计原生仿招商银行首页原生Android Socket 即时通讯Rea…

Android MVVM开发框架

MVVM 数据双向绑定&#xff0c;通过数据驱动UI&#xff0c;M提供数据&#xff0c;V视图&#xff0c;VM即数据驱动层 MVP框架图 &#xff08;图片来源于网络&#xff09; 学习MVVM开发框架&#xff0c;要先了解DataBinding&#xff0c;DataBinding 是什么&#xff1f; DataBi…

Android: 开发框架设计

Android 开发框架 Android运用框架的目的不外乎是实现代码的代码解耦、逻辑分类、快速集成 便于维护等目的&#xff1b;Android 开发架构从早期的MVC &#xff0c;到近年到MVP 架构&#xff0c;到最近流行到MVVM 架构。不断到对业务逻辑、代码结构进行分层&#xff0c;便于快速…

安卓框架

http://www.cnblogs.com/jincheng-yangchaofan/articles/7018780.html 框架&#xff1a;提供一定能力的小段程序 一.榜单介绍 排行榜包括四大类&#xff1a; 单一框架&#xff1a;仅提供路由、网络层、UI层、通信层或其他单一功能的框架 混合开发框架&#xff1a;提供开发hy…

安卓应用开发顶级框架大盘点,总有一款适合你

作者 | Slava Vaniukov 译者 | 苏本如&#xff0c;责编 | 夕颜 封图 | CSDN下载自视觉中国 出品 | CSDN&#xff08;ID:CSDNnews&#xff09; 随着软件开发向移动应用的转变&#xff0c;越来越多的企业意识到&#xff0c;移动应用程序对于企业和客户之间建立牢固的联系至关重要…

嵌入式Android底层开发(一)——安卓开发的整体框架与简述

一、Android简介 Android是一种基于Linux内核&#xff08;不包含GUN组件&#xff09;的自由及开放源代码的操作系统&#xff0c;主要使用于移动设备&#xff0c;如智能手机和平板电脑&#xff0c;由美国Google公司和开放手机联盟领导及开发。 主要参数表&#xff1a; 参数上…

Android 框架

背景 我们有一个需求&#xff1a;我们需要查询用户账号信息&#xff0c;用户输入账号&#xff0c;点击按钮可进行查询账号信息&#xff0c;如果查询数据成功&#xff0c;则将数据展示在界面上&#xff1b;如果查询数据失败&#xff0c;则在界面上提升获取数据失败。 假如说我们…

Android - 框架使用

目录 1 Gson解析JSON 1.1 引入依赖 1.2 使用 1.3 安装插件 1.4 Demo 2 下滑刷新&#xff0c;上滑加载新数据 2.1 背景 2.2 引入依赖 2.3 代码实现 3 加载网络图片 3.1 背景 3.2 引入依赖 3.3 代码实现 4 轮播图 4.1 引入依赖 4.2 代码实现 5 网络数据请求 Re…

Android 快速开发框架 集成框架

由于自己经常写项目&#xff0c;没有一个方便开发的一套框架怎么行&#xff0c;所以在日常开发总自己整理了一套&#xff0c;请各位过目&#xff0c;不喜勿喷。一个新项目搭建需要具备的环境:先导入我制作的jar包。添加必要的权限。需要一个Application初始化数据,下面开始调用…

Android应用-开发框架设计

目录 1. &#x1f4c2; 简介 1.1 背景 1.2 专业术语 2. &#x1f531; 总体设计思想 2.1 分层&#xff1a;组件化设计框架 2.2 分类&#xff1a;应用开发架构图 3. ⚛️ 框架详细设计 3.1 组件化框架外形 3.2 业务模块化 3.3 代码编程框架 4. &#x1f4a0; 框架其他…

Android常用框架

1.缓存框架 1.1DiskLruCache&#xff1a;Java实现基于LRU的磁盘缓存&#xff0c;DiskLruCache不是google官方所写&#xff0c;但是得到了官方推荐&#xff0c;DiskLruCache没有编写到SDK中去&#xff0c;如需使用可直接copy这个类到项目中去。使用场景&#xff1a;如“清除…

Android开发框架大全

包括各种快速开发框架、测试框架、系统框架、插件补丁框架、设计模式框架、主题切换框架。 android-tips-tricks&#xff1a; https://github.com/nisrulz/android-tips-tricks Android 开发的一些 Tips 集合 Android-Code-Style&#xff1a; https://github.com/LoranWong/And…

Android开发常用开源框架

Android开源框架系列 Android开源项目 Android开发常用开源框架2 Android开发常用开源框架3 GitHub上最火的Android开源项目,所有开源项目都有详细资料和配套视频 2017年伊始&#xff0c;你需要尝试的25个Android第三方库 Android开发常用第三方平台 免费的计算机编程类中…