Java解析XML(DOM解析和SAX解析)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Java解析XML(DOM解析和SAX解析)

前言:在程序中访问和操作XML文件一般有两种模型:DOM(文档对象模型)和流模型;在本篇文章中分别对应DOM解析和SAX解析。

1 .DOM解析与SAX解析的相关知识点

1.1 DOM

  • 文档对象模型(Document Object Model,简称DOM),是W3C制定的标准接口规范,是一种处理HTML和XML文件的标准API。
  • 将HTML或XML文档转化为DOM树的过程称为解析(parse)。HTML文档被解析后,转化为DOM树,因此对HTML文档的处理可以通过对DOM树的操作实现。DOM模型不仅描述了文档的结构,还定义了结点对象的行为,利用对象的方法和属性,可以方便地访问、修改、添加和删除DOM树的结点和内容。
  • DOM分为HTML DOM和XML DOM两种。它们分别定义了访问和操作HTML和XML文档的标准方法,并将对应的文档呈现为带有元素、属性和文本的树结构(节点树),如下图所示。
    1. DOM树定义了HTML/XML文档的逻辑结构,给出了一种应用程序访问和处理XML文档的方法。
    2. 在DOM树中,有一个根节点,所有其他的节点都是根节点的后代。
    3. 在应用过程中,基于DOM的HTML/XML分析器将一个HTML/XML文档转换成一棵DOM树,应用程序通过对DOM树的操作,来实现对HTML/XML文档数据的操作。
      在这里插入图片描述
      来自百度百科

1.2 DOM解析

  • DOM是基于属性结构的XML解析方式,会将整个XML文档读入内存并构建一个DOM树,基于这棵树型结构对各个节点进行操作。XML文档中每个成分都是一个节点,整个文档是一个文档节点,每个XML标签对应一个元素节点,包含在XML标签中的文本是文本节点,每一个XML属性是一个属性节点,注释属于注释节点。

  • DOM树所提供的随机访问方式很灵活方便,可以任意地控制整个XML文档中的内容,但是DOM分析器把整个XML文件转化为DOM树放到了内存中,即在处理过程中整个文档都表示在内存中。当文档比较大或者结构比较复杂时,对内存需求比较高。

1.3 SAX解析

  • JAVA 解析 XML 通常有两种方式:DOM 和SAX。DOM(文档对象模型)是W3C标准,提供了标准的解析方式,但其解析效率一直不尽如人意,这是因为DOM解析XML文档时,把所有内容一次性的装载入内存,并构建一个驻留在内存中的树状结构(节点树),图见章节1.1。如果需要解析的XML文档过大,或者我们只对该文档中的一部分感兴趣,这样就会引起性能问题。
  • SAX(simple API for XML)是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。而且相比于DOM,SAX可以在解析文档的任意时刻停止解析,但任何事物都有其相反的一面,对于SAX来说就是操作复杂。

1.4 DOM解析与SAX解析对比

DOM SAX
基于树 ,在内存中是持久的,可以修改其内容 基于事件,类似于流媒体,分析能够立即开始,而不是等待所有的数据被处理
在内存中建立文件树,不适于处理大型的XML文件。 依序读入文件并产生相对应事件,可以处理任何大小的XML文件。
可以随意存取文件树的任何部分,没有次数限制 只能对文件按顺序剖析一遍,不支持对文件的随意存取
可以随意修改文件树,从而修改了XML文件 只能读取XML文件内容,而不能修改
易于理解,易于开发 开发上比较复杂,需要自己来制作事件处理器
已经在DOM基础之上建立了文件树 对工作人员更灵活,可以用SAX建立自己的XML对象模型

SAX 和 DOM 不是相互排斥的,我们可以使用 DOM 来创建 SAX 事件流,也可以使用 SAX 来创建 DOM 树。

1.5 XML与HTML的区别

XML HTML
XML即ExtentsibleMarkup Language(可扩展标记语言),是用来定义其它语言的一种元语言,其前身是SGML(标准通用标记语言)。 HTML(HyperTextMark-upLanguage)即超文本标记语言,是WWW的描述语言。
XML被设计用来描述数据,其焦点是数据的内容 HTML被设计用来显示数据,其焦点是数据的外观。
xml将数据和显示分开。 Html将数据和显示结合在一起,在页面中把这数据显示出来
xml是用来描述数据、存放数据的,所以可以作为持久化的介质 html是用来显示数据的
XML标签是免费的、自定义的、可扩展的 Html标签是预定义的
在xml中严格区分大小写 在html中不区分大小写
在XML中,是严格的树状结构,绝对不能省略掉结束标记。 在HTML中,有时不严格,如果上下文清楚地显示出段落或者列表键在何处结尾,那么你可以省略</p>或者</li>之类的结束标记。
在XML中,属性值必须分装在引号中 在HTML中,引号是可用可不用的。
在XML中,所有的属性都必须带有相应的值。 在HTML中,可以拥有不带值的属性名。
在XML文档中,空白部分不会被解析器自动删除。 html是可以过滤掉空格的。
xml没有固有的标记 html使用固有的标记,如</p>或者</li>

2.Java中关于DOM解析实战(Dom4j解析)

本人之前写过关于Dom4j解析的博客,具体请参见本人另外一篇博客https://blog.csdn.net/MrYushiwen/article/details/113182481

ps:导包注意不要导错了,是org.dom4j下的包。
在这里插入图片描述
另外在 mybatis 中,解析XML文件采用的是DOM + XPath 方式进行对配置文件的加载和解析
XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言。 是一种为查询 XML 文档而设计的语言, 因为 DOM 解析 XML 的方式会将整个 XML 内容加载到内存并形成树形结构,所以 XPath 可以配合 DOM 进行对 XML 的解析。
在这里插入图片描述
上述图片来自百度百科,对于XPath感兴趣的同学可以参考百度百科,上面描述得很清楚,链接:https://baike.baidu.com/item/XPath/5574064


3.DOM方式解析XML的时候encoding属性的作用

规定:

W3C定义了三条XML解析器如何正确读取XML文件的编码的规则:

  1. 如果文本文件头部有BOM(Byte Order Mark),即字节顺序标记(它是在Unicode编码标准中用于标识文件是采用哪种格式的编码),就按照BOM来。
  2. 如果没有BOM,就查看XML声明的编码属性。
  3. 如果上述两个都没有,就假定XML文档采用UTF-8编码。

也就是说XML解析器首先根据文件的BOM来解析文件;如果没找到BOM,由用XML里的encoding属性指定的编码;如果xml里encoding没指定的话,就默认用utf-8来解析文档。然后又可以推出,BOM和ENCODING都有的话,则以BOM指定的为准。

具体内容见本人另一篇博文:https://blog.csdn.net/MrYushiwen/article/details/121925364

3.SAX解析

注意导包不要导错了

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.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;

public class SAXParseDemo {
    
    public static void main(String[] args) {
    
        //1.创建解析工厂
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        //2.创建解析器
        try {
    
            SAXParser saxParser = saxParserFactory.newSAXParser();
            //3.通过解析器的parse方法
            saxParser.parse("C:\\Users\\yclw060\\Desktop\\11.xml",new MyDefaultHandler());
        } catch (ParserConfigurationException e) {
    
            e.printStackTrace();
        } catch (SAXException e) {
    
            e.printStackTrace();
        } catch (IOException e) {
    
            e.printStackTrace();
        }

    }
}

class MyDefaultHandler extends DefaultHandler{
    
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
    
        //找到开始标签,输出标签名
        System.out.println(qName);
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
    
        //标签内的文体生成String,然后输出
        System.out.println(new String(ch,start,length));
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
    
        //输出结束标签名
        System.out.println(qName);
    }
}

4.JAXP简介

JAXP(Java API for XMLProcessing,意为XML处理的Java API)是Java XML程序设计的应用程序接口之一,它提供解析和验证XML文档的能力。
JAXP解析XML的三种基本接口为:

文档对象模型解析接口或DOM接口XML简单API解析接口或SAX接口XML流API或StAX接口(是JDK 6的一部分,为JDK 5提供单独的包)除了解析接口,JAXP还提供了XSLT接口用来对XML文档进行数据和结构的转换。

上面3个章节中已对前两种解析方式做了具体分析,下面对剩下的两种方式做简要说明:

4.1 StAX接口

全称 Streaming API for XML,一种全新的,基于流的JAVA XML解析标准类库。StAX 解析方式和 SAX 解析方式相似,它也是把 XML 文档作为一个事件流进行处理,但不同之外在于 StAX 采用的是拉模式,而SAX采用的是推方式。 推模型:就是我们常说的SAX,它是一种靠事件驱动的模型。当它每发现一个节点就引发一个事件,而我们需要编写这些事件的处理程序。这样的做法很麻烦,且不灵活。拉模型:在遍历文档时,会把感兴趣的部分从读取器中拉出,不需要引发事件,允许我们选择性地处理节点。这大大提高了灵活性,以及整体效率StAX的设计介于DOM和SAX接口之间,在它的隐喻中,程序的入口点是一个代表文档中一个位置的光标。应用程序可以按需向前移动光标 – 从解析器中“拉”出信息。这与基于事件的API(如SAX)不同,SAX将数据“推”给应用程序,要求应用程序维护事件间的状态,如果应用需要知道在文档中的位置信息。

4.2 XSLT接口

简介:

XSLT(可扩展样式表转换语言)允许将XML文档转换为数据其他形式。应用程序使用javax.xml.transform包中的接口可以进行XSLT转换。接口最初被称为TrAX (Transformation API for XML),是由许多Java XSLT处理器的开发人员通过非正式协作开发的。

接口的主要特性包括:

工厂类javax.xml.transform.TransformerFactory可以使应用动态地选择使用哪一个XSLT处理器。TransformerFactory上的方法用来创建javax.xml.transform.Templates对象, 表示样式表的编译后的形式。这是一个线程安全的对象,可以重复使用,顺序或并发,在多个源文档上应用同一个样式表(或用用一个源文档,不同的参数)Templates上的方法可以创建javax.xml.transform.Transformer,表示样式表的可执行形式。Transformer不可以在线程间共享,虽然也是可重用的。Transformer提供方法设置样式表参数和序列化选项(例如,输出是否缩进),以及一个实际运行转换的方法。JAXP定义了javax.xml.transform.Source和javax.xml.transform.Result两个抽象接口来表示转换的输入和输出。某种程度上,这是非常规使用Java接口,这是因为并不期待一个处理器会接受任何实现该接口的类,每一个处理器可以选择支持那些Source和Result的处理。实际上所有JAXP处理器支持三种标准类型的Source (DOMSource,SAXSource,StreamSource)以及三种标准类型的Result (DOMResult,SAXResult,StreamResult)以及处理器自己的实现。
来自百度百科
目录
相关文章
|
16天前
|
JavaScript 前端开发 Go
CSS 与 JS 对 DOM 解析和渲染的影响
【10月更文挑战第16天】CSS 和 JS 会在一定程度上影响 DOM 解析和渲染,了解它们之间的相互作用以及采取适当的优化措施是非常重要的。通过合理的布局和加载策略,可以提高网页的性能和用户体验,确保页面能够快速、流畅地呈现给用户。在实际开发中,要根据具体情况进行权衡和调整,以达到最佳的效果。
|
5天前
|
存储 Java 编译器
Java内存模型(JMM)深度解析####
本文深入探讨了Java内存模型(JMM)的工作原理,旨在帮助开发者理解多线程环境下并发编程的挑战与解决方案。通过剖析JVM如何管理线程间的数据可见性、原子性和有序性问题,本文将揭示synchronized关键字背后的机制,并介绍volatile关键字和final关键字在保证变量同步与不可变性方面的作用。同时,文章还将讨论现代Java并发工具类如java.util.concurrent包中的核心组件,以及它们如何简化高效并发程序的设计。无论你是初学者还是有经验的开发者,本文都将为你提供宝贵的见解,助你在Java并发编程领域更进一步。 ####
|
18天前
|
存储 Java
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
33 3
|
16天前
|
设计模式 算法 安全
实时操作系统(RTOS)深度解析及Java实现初探
【10月更文挑战第22天】实时操作系统(RTOS,Real-Time Operating System)是一种能够在严格的时间限制内响应外部事件并处理任务的操作系统。它以其高效、高速、可靠的特点,广泛应用于工业自动化、航空航天、医疗设备、交通控制等领域。本文将深入浅出地介绍RTOS的相关概念、底层原理、作用与功能,并探讨在Java中实现实时系统的方法。
46 1
|
10天前
|
安全 Java 测试技术
🎉Java零基础:全面解析枚举的强大功能
【10月更文挑战第19天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
96 60
|
3天前
|
存储 设计模式 分布式计算
Java中的多线程编程:并发与并行的深度解析####
在当今软件开发领域,多线程编程已成为提升应用性能、响应速度及资源利用率的关键手段之一。本文将深入探讨Java平台上的多线程机制,从基础概念到高级应用,全面解析并发与并行编程的核心理念、实现方式及其在实际项目中的应用策略。不同于常规摘要的简洁概述,本文旨在通过详尽的技术剖析,为读者构建一个系统化的多线程知识框架,辅以生动实例,让抽象概念具体化,复杂问题简单化。 ####
|
2天前
|
存储 分布式计算 Java
存算分离与计算向数据移动:深度解析与Java实现
【11月更文挑战第10天】随着大数据时代的到来,数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构,即计算资源与存储资源紧密耦合,在处理海量数据时逐渐显露出其局限性。为了应对这些挑战,存算分离(Disaggregated Storage and Compute Architecture)和计算向数据移动(Compute Moves to Data)两种架构应运而生,成为大数据处理领域的热门技术。
13 2
|
2天前
|
设计模式 安全 Java
Java编程中的单例模式深入解析
【10月更文挑战第31天】在编程世界中,设计模式就像是建筑中的蓝图,它们定义了解决常见问题的最佳实践。本文将通过浅显易懂的语言带你深入了解Java中广泛应用的单例模式,并展示如何实现它。
|
11天前
|
存储 安全 Java
系统安全架构的深度解析与实践:Java代码实现
【11月更文挑战第1天】系统安全架构是保护信息系统免受各种威胁和攻击的关键。作为系统架构师,设计一套完善的系统安全架构不仅需要对各种安全威胁有深入理解,还需要熟练掌握各种安全技术和工具。
40 10
|
10天前
|
Java 程序员 开发者
Java中的异常处理机制深度解析####
本文将深入浅出地探讨Java编程语言中异常处理的核心概念与实践策略,旨在帮助开发者更好地理解如何构建健壮的应用程序。通过剖析异常体系结构、掌握有效的异常捕获与处理技巧,以及学习最佳实践,读者能够提升代码质量,减少运行时错误,从而增强软件的稳定性和用户体验。 ####

推荐镜像

更多