XML是一种通用的数据交换格式,它的平台无关性、语言无关性、系统无关性、给数据集成与交互带来了极大的方便。XML在不同的语言环境中解析方式都是一样的,只不过实现的语法不同而已。

对于XML的解析,还有一些方便的XML解析工具,如JAXB、XStream这样的解析工具,它们利用注解、反射等非常方便地帮助我们实现从XML解析为Java对象,还有如Dom4j,它是一个易用的、开源的库,特别是对进行读取和修改XML文件内容提供了丰富的API接口,易操作、高效率,但是它对于XML内容和JAVA对象之间的映射转换却不太如JAXB和XStream。

一、DOM解析

  DOM的全称是Document Object Model,也即文档对象模型。在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序正是通过对这个对象模型的操作,来实现对XML文档数据的操作。通过DOM接口,应用程序可以在任何时候访问XML文档中的任何一部分数据,因此,这种利用DOM接口的机制也被称作随机访问机制。

  DOM接口提供了一种通过分层对象模型来访问XML文档信息的方式,这些分层对象模型依据XML的文档结构形成了一棵节点树。无论XML文档中所描述的是什么类型的信息,即便是制表数据、项目列表或一个文档,利用DOM所生成的模型都是节点树的形式。也就是说,DOM强制使用树模型来访问XML文档中的信息。由于XML本质上就是一种分层结构,所以这种描述方法是相当有效的。

  DOM树所提供的随机访问方式给应用程序的开发带来了很大的灵活性,它可以任意地控制整个XML文档中的内容。然而,由于DOM分析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或者结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项耗时的操作。所以,DOM分析器对机器性能的要求比较高,实现效率不十分理想。不过,由于DOM分析器所采用的树结构的思想与XML文档的结构相吻合,同时鉴于随机访问所带来的方便,因此,DOM分析器还是有很广泛的使用价值的。

    优点:

      1、形成了树结构,有助于更好的理解、掌握,且代码容易编写。

      2、解析过程中,树结构保存在内存中,方便修改。

    缺点:

      1、由于文件是一次性读取,所以对内存的耗费比较大。

      2、如果XML文件比较大,容易影响解析性能且可能会造成内存溢出。

DOM解析示例:

项目目录结构

1.DOM解析

TestXML.java文件

import java.io.FileReader;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;//采用DOM进行解析
//DOM的读取时是将XML整个文件装载成DOM树,即使文档中有不需要的信息时也会被装载进来,在大多数的时候DOM是非常方便好用的。
public class TestXMl {public static void main(String[] args) {// 文档构建器的工厂DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();// 得到XML文档构建器try {DocumentBuilder db = dbf.newDocumentBuilder();// 1.得到XML文档对象// 当test.xml放在本项目的根目录时(和src bin同一目录下时)// db.parse("test.xml");// 当test.xml放在bin目录下时String path = FileReader.class.getResource("/").getFile();/// System.out.println(path);// 导入的是org.w3c.dom.Document;Document doc = db.parse(path + "test.xml");// 得到文档根节点Element root = doc.getDocumentElement();String rootName = root.getNodeName();System.out.println(rootName);NodeList list = doc.getElementsByTagName("People");// 2.获取XML中的节点System.out.println("当前有几个People:" + list.getLength());// 3.得到节点里面的有用信息for (int i = 0; i < list.getLength(); i++) {Element peopleElement = (Element) list.item(i);String id = peopleElement.getAttribute("id"); // 获取id的属性值System.out.println("id:" + id);// 遍历当前元素的子节点NodeList childNodeList = peopleElement.getChildNodes();// test.xml中一个People元素下有Name和Age两个标签,但是它把回车也算作一个节点,所以打印出来是五个// 第一个是没有回车的,第二个有System.out.println("子节点个数:" + childNodeList.getLength());// 判断这些子节点中的元素是不是有效的元素,即不为回车for (int j = 0; j < childNodeList.getLength(); j++) {// 判断是不是元素,有标签的,若是元素才把它转换为元素if (childNodeList.item(j) instanceof Element) {Element cElement = (Element) childNodeList.item(j);String tagName = cElement.getTagName();String content = cElement.getTextContent();System.out.println(tagName + ":" + content);}}}} catch (ParserConfigurationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SAXException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}

2.往XML文件中写入的是Document对象

Write.java文件


import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;//由对象到文件,把document对象保存到文件中
//XML是磁盘文件,DOM是内存对象。
//往XML文件中写入的是Document对象,所以要编辑XML文件,实际上编辑的是Document文档对象。
public class WriteXML {public static void main(String[] args) {//创建一个document,通过builder创建DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();try {DocumentBuilder db = dbf.newDocumentBuilder();Document doc = db.newDocument();//通过document创建节点ElementElement stuEle = doc.createElement("Student");stuEle.setAttribute("stuNo","S1001");//给stuEle添加子节点Element nameEle = doc.createElement("Name");//方式一:创建一个文本节点/*Text txtName = doc.createTextNode("zhangsan");nameEle.appendChild(txtName);*///方式二:直接添加文本nameEle.setTextContent("zhangsan");Element ageEle = doc.createElement("Age");ageEle.setTextContent("20");stuEle.appendChild(nameEle);stuEle.appendChild(ageEle);//将Element对象添加到document中doc.appendChild(stuEle);//将document对象保存到硬盘文件xml中//通过transformer进行保存TransformerFactory tf = TransformerFactory.newInstance();Transformer former = tf.newTransformer();former.transform(new DOMSource(doc), new StreamResult("stu.xml"));System.out.println("生成xml成功...");} catch (ParserConfigurationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (TransformerConfigurationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (TransformerException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}

test.xml

<?xml version="1.0" encoding="UTF-8"?>
<PeopleList><People id="1"><Name en="zhangsan">张三</Name><Age>20</Age><Address>苏州</Address></People><People id="2"><Name en="lisi">李四</Name><Age>39</Age><Address>常州</Address></People><People id="3"><Name en="wangwu">王五</Name><Age>14</Age><Address>杨州</Address></People><People id="4"><Name en="zhaowu">赵武</Name><Age>31</Age><Address>贵州</Address></People><People id="5"><Name en="sunliu">孙刘</Name><Age>26</Age><Address>广州</Address></People>
</PeopleList>

二、SAX解析

  SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。

    优点:

      1、采用事件驱动模式,对内存耗费比较小。

      2、适用于只处理XML文件中的数据时。

    缺点:

      1、编码比较麻烦。

      2、很难同时访问XML文件中的多处不同数据。

SAX解析示例

      XMLHandler.java


import java.util.ArrayList;
import java.util.List;import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;public class XMLHandler extends DefaultHandler {private String value; //读取到的文本private People people; //临时存放的一个人private List<People> peopleList;public List<People> getPeopleList() {return peopleList;}//当读到文档开始处触发事件,该方法只执行一次@Overridepublic void startDocument() throws SAXException {// TODO Auto-generated method stubsuper.startDocument();System.out.println("开始执行startDocument,开始读取xml文档");peopleList = new ArrayList<People>();}//当读到文档结束处触发事件,该方法只执行一次@Overridepublic void endDocument() throws SAXException {// TODO Auto-generated method stubsuper.endDocument();System.out.println("开始执行endDocument,结束读取xml文档");}//当读到元素开始处触发事件@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {// TODO Auto-generated method stubsuper.startElement(uri, localName, qName, attributes);System.out.println("开始执行startElement,开始读取xml文档的标签,该标签为:"+qName);if("People".equals(qName)) {people = new People();System.out.println("当前people有属性"+attributes.getLength());for(int i = 0;i<attributes.getLength();i++) {//获取当前属性名if("id".equals(attributes.getQName(i))) {people.setId(attributes.getValue(i));}}}}//当读到元素结束处触发事件@Overridepublic void endElement(String uri, String localName, String qName) throws SAXException {// TODO Auto-generated method stubsuper.endElement(uri, localName, qName);System.out.println("开始执行endElement,结束读取xml文档的标签,该标签为:"+qName);if("People".equals(qName)) {peopleList.add(people);people = null;}else if("Name".equals(qName)) {  //读到Name的结束标签people.setName(value);}else if("Age".equals(qName)) {people.setAge(value);}}//读到内容时触发事件@Overridepublic void characters(char[] ch, int start, int length) throws SAXException {// TODO Auto-generated method stubsuper.characters(ch, start, length);value = new String(ch,start,length);System.out.println("当前读到的文本是:"+value);}}

ReadXMLBySAX.java

import java.io.IOException;
import java.util.List;import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;import org.xml.sax.SAXException;//SAX解析
//流读取的机制(SAX),Document的读取在内部也是使用流的机制去读的。
//流读取的机制是只负责读取,不进行存储,但是会给出一定的关键的事件,提示你进行相应的保存操作。
public class ReadXMLBySAX {public static void main(String[] args) {//得到saxParserSAXParserFactory  factory = SAXParserFactory.newInstance();try {SAXParser parser = factory.newSAXParser();XMLHandler handler = new XMLHandler();//通过saxParse接卸器的parse方法,解析xml,parse需要一个处理器,handlerparser.parse("test.xml", handler);List<People> list = handler.getPeopleList();System.out.println("一共读取倒了"+list.size()+"个人");for(People people : list) {System.out.println(people);}} catch (ParserConfigurationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SAXException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}

People.java


public class People {private String id;private String name;private String age;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public People(String id, String name, String age) {super();this.id = id;this.name = name;this.age = age;}public People() {super();}@Overridepublic String toString() {// TODO Auto-generated method stubreturn "Student[id="+id+",name="+name+",age="+age+"]";}}

XML解析---DOM解析和SAX解析相关推荐

  1. android用sax解析xml,详解android使用SAX解析XML文件

    解析XML的方式有很多种,大家比较熟悉的可能就是DOM解析. DOM(文件对象模型)解析:解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以根据DOM接口来操作这个树结构了. 优点:整个 ...

  2. android xml sax解析,《android用SAX解析xml》

    主要的Acivity package com.xml.xml; import java.io.Serializable; import java.util.ArrayList; import java ...

  3. java sax解析xml_在Java中使用DOM,SAX和StAX解析器解析XML

    java sax解析xml 我碰巧通读了有关Java中XML解析和构建API的章节. 我试用了样本XML上的其他解析器. 然后,我想在我的博客上分享它,这样我就可以得到该代码的参考以及任何阅读此代码的 ...

  4. XML的SAX解析以及DOM解析和SAX解析区别

    前言: XML解析工具 DOM解析原理:1)JAXP (oracle-Sun公司官方)2)JDOM工具(非官方)3)Dom4J工具(非官方)三大框架(默认读取xml的工具就是Dom4j)....... ...

  5. Android[中级教程]第六章 XML解析之SAX解析器

    Android[中级教程]第六章 XML解析之SAX解析器 分类: Android中级2011-10-06 01:52 125人阅读 评论(1) 收藏 举报 接上一章,这一章我们就来学习SAX解析器, ...

  6. python 使用sax 解析xml 文件

    这里不是说xml 的所以如果xml 不了解,可以百度大致看下即可, SAX知识了解 SAX (simple API for XML )  有解析器和事件处理器 解析器负责读取XML文档,并向事件处理器 ...

  7. python解析xml文件elementtree_Python中使用ElementTree解析XML示例

    [XML基本概念介绍] XML 指可扩展标记语言(eXtensible Markup Language). XML 被设计用来传输和存储数据. 概念一: 复制代码 代码如下: # foo元素的起始标签 ...

  8. 解析XML方式-DOM,SAX

    students.xml <?xml version="1.0" encoding="UTF-8"?> <students><st ...

  9. 解析XML报文--------DOM、JDOM、SAX

    例: <?xml version="1.0" encoding="UTF-8"?> <bookstore><book id=&qu ...

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

    前言:在程序中访问和操作XML文件一般有两种模型:DOM(文档对象模型)和流模型:在本篇文章中分别对应DOM解析和SAX解析. 目录 1 .DOM解析与SAX解析的相关知识点 1.1 DOM 1.2 ...

最新文章

  1. 【英文文本分类实战】之四——词典提取与词向量提取
  2. centos 8 卸载anaconda_Centos7安装JDK1.8
  3. permission denied和linux赋值权限chmod命令
  4. C++ 基础概念、语法和易错点整理
  5. c# out关键字 vb_在c#中使用out关键字
  6. arn linux编译系统时错误的解决
  7. vmware中NAT模式下,虚拟机与主机能ping通 为什么虚拟机不能上网
  8. java 内部错误2753_重新安装java出现错误的解决方法
  9. 天梯—计算阶乘和(C语言)
  10. python儿童入门视频-Python入门视频课程
  11. 允许外部访问Windows本机的指定端口
  12. linux下实用工具,Linux下的实用工具(持续更新)
  13. 如何在基于对话框的程序中动态设置鼠标指针
  14. Arcgis Server服务中rest服务和wms服务的对应关系
  15. 现代信号处理——自适应滤波器(RLS自适应滤波器)
  16. 2018-2019-1 20165301 20165304 20165314 实验二 固件程序设计
  17. 键盘上每个键作用!!! (史上最全的)
  18. 微信小程序利用canvas绘制一个动画百分比圆圈
  19. cmpp 免提短信(闪信)
  20. Lync 2010升级到Lync 2013之设定Lync Mobile!

热门文章

  1. 硬件知识:32-64位电脑?操作系统?软件?
  2. 如何免费将多张JPG图片转成PDF格式操作方法分享
  3. Java中的方法签名
  4. uniapp使用iconfont
  5. 唐金州的Vue开发实战学习笔记(生态篇)
  6. 解读欧债危机-时寒冰
  7. “双鸭山大学”、“五道口男子职技学校”……你的大学绰号叫啥?
  8. Linux常用搜索命令
  9. JavaScript实现银行ATM机取款
  10. 中北大学算法分析与设计实验报告六(最大团问题)