感谢http://blog.csdn.net/redarmy_chen/article/details/12951649(关于SAX解析)以及http://blog.csdn.net/zhangerqing/article/details/8253532(DOM解析)。首先申明本文并非个人原创,而是整合的前面两篇文章,供大家以及自己参考。

1.XML

XML是一种对独立于任何编程语言的数据进行编码的机制。主要用于数据存储,数据传输以及配置文件(Ioc)等方面。XML要求所有的标记必须成对出现,且区分大小写。举个例子:

<bookstore>
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="CHILDREN">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="WEB">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
</bookstore>

可以从这个例子,得出XML的结构,简单说XML的结构即为多叉树结构。上面代码的结构图如下:

2.XML的解析技术

DOM

DOM 是 W3C 处理 XML 的标准 API,它是许多其它与 XML 处理相关的标准的基础,不仅是 Java,其它诸如 Javascript,PHP,MS .NET 等等语言都实现了该标准, 成为了应用最为广泛的 XML 处理方式。当然,为了能提供更多更加强大的功能,Java 对于 DOM 直接扩展工具类有很多,比如很多 Java 程序员耳熟能详的 JDOM,DOM4J 等等, 它们基本上属于对 DOM 接口功能的扩充,保留了很多 DOM API 的特性。其处理方式是将 XML 整个作为类似树结构的方式读入内存中以便操作及解析,因此支持应用程序对 XML 数据的内容和结构进行修改,但是同时由于其需要在处理开始时将整个 XML 文件读入到内存中去进行分析,因此其在解析大数据量的 XML 文件时会遇到类似于内存泄露以及程序崩溃的风险。例子如下:

首先造一个xml文档出来:(books.xml放在项目根路径下,不是src,可以在工程文件所在文件夹根目录下先创建txt文档,编辑books内容,然后保存为xml格式即可)

<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="01" name="book1">
<title>Harry Potter</title>
<author>J K. Rowling</author>
</book>
<book id="02" name="book2">
<title>Thinking in Java</title>
<author>Bruke</author>
</book>
</books>

  DOM 解析:

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList; public class DOMTest { /* build a DocumentBuilderFactory */
DocumentBuilderFactory builderFactory = DocumentBuilderFactory
.newInstance(); public static void main(String[] args) {
DOMTest parser = new DOMTest();
Document document = parser.parse("books.xml");
/* get root element */
Element rootElement = document.getDocumentElement(); /* get all the nodes whose name is book */
NodeList nodeList = rootElement.getElementsByTagName("book");
if (nodeList != null) {
for (int i = 0; i < nodeList.getLength(); i++) {
/* get every node */
Node node = nodeList.item(i);
/* get the next lever's ChildNodes */
NodeList nodeList2 = node.getChildNodes();
for (int j = 0; j < nodeList2.getLength(); j++) {
Node node2 = nodeList2.item(j);
if (node2.hasChildNodes()) {
System.out.println(node2.getNodeName() + ":"
+ node2.getFirstChild().getNodeValue());
}
}
}
}
} /* Load and parse XML file into DOM */
public Document parse(String filePath) {
Document document = null;
try {
/* DOM parser instance */
DocumentBuilder builder = builderFactory.newDocumentBuilder();
/* parse an XML file into a DOM tree */
document = builder.parse(new File(filePath));
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return document;
}
}

输出:

title:Harry Potter
  author:J K. Rowling
  title:Thinking in Java
  author:Bruke

SAX:

SAX解析XML文件采用事件驱动的方式进行,也就是说,SAX是逐行扫描文件,遇到符合条件的设定条件后就会触发特定的事件,回调你写好的事件处理程序。使用SAX的优势在于其解析速度较快,相对于DOM而言占用内存较少。而且SAX在解析文件的过程中得到自己需要的信息后可以随时终止解析,并不一定要等文件全部解析完毕。凡事有利必有弊,其劣势在于SAX采用的是流式处理方式,当遇到某个标签的时候,它并不会记录下以前所遇到的标签,也就是说,在处理某个标签的时候,比如在startElement方法中,所能够得到的信息就是标签的名字和属性,至于标签内部的嵌套结构,上层标签、下层标签以及其兄弟节点的名称等等与其结构相关的信息都是不得而知的。实际上就是把XML文件的结构信息丢掉了,如果需要得到这些信息的话,只能你自己在程序里进行处理了。

SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器:
  解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。
  解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
  事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。

以SAX的ContentHandler接口为例,了解常用方法:startElement、endElement、characters等:

startElement方法说明:

void startElement(String uri,
String localName,
String qName,
Attributes atts)
throws SAXException
方法说明:
解析器在 XML 文档中的每个元素的开始调用此方法;对于每个 startElement 事件都将有相应的 endElement 事件(即使该元素为空时)。所有元素的内容都将在相应的 endElement 事件之前顺序地报告。 参数说明:
uri - 名称空间 URI,如果元素没有名称空间 URI,或者未执行名称空间处理,则为空字符串
localName - 本地名称(不带前缀),如果未执行名称空间处理,则为空字符串
qName - 限定名(带有前缀),如果限定名不可用,则为空字符串
atts - 连接到元素上的属性。如果没有属性,则它将是空 Attributes 对象。在 startElement 返回后,此对象的值是未定义的

endElement方法说明:

void endElement(String uri,
String localName,
String qName)
throws SAXException接收元素结束的通知。
SAX 解析器会在 XML 文档中每个元素的末尾调用此方法;对于每个 endElement 事件都将有相应的 startElement 事件(即使该元素为空时)。 参数:
uri - 名称空间 URI,如果元素没有名称空间 URI,或者未执行名称空间处理,则为空字符串
localName - 本地名称(不带前缀),如果未执行名称空间处理,则为空字符串
qName - 限定的 XML 名称(带前缀),如果限定名不可用,则为空字符串

characters方法:

void characters(char[] ch,
int start,
int length)
throws SAXException
接收字符数据的通知,可以通过new String(ch,start,length)构造器,创建解析出来的字符串文本.
参数:
ch - 来自 XML 文档的字符
start - 数组中的开始位置
length - 从数组中读取的字符的个数

下面我们就具体讲解sax解析的操作:

一.我们通过XMLReaderFactory、XMLReader完成,步骤如下

1.通过XMLReaderFactory创建XMLReader对象
XMLReader reader = XMLReaderFactory.createXMLReader();
2. 设置事件处理器对象
reader.setContentHandler(new MyDefaultHandler());
3.读取要解析的xml文件
FileReader fileReader =new FileReader(new File("src\\sax\\startelement\\web.xml"));
4.指定解析的xml文件
reader.parse(new InputSource(fileReader));

案例:通过案例对uri、localName、qName和attribute参数有更加深入的了解

1.首先创建要解析的web.xml文件,内容如下

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns:csdn="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<csdn:display-name></csdn:display-name>
</web-app>
<!--
uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。
xml namespace-xmlns
localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。
qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。
attributes - 附加到元素的属性。如果没有属性,则它将是空的 Attributes 对象。
-->

2.创建解析测试类及事件处理的内部类代码如下

package sax.startelement;  

import java.io.File;
import java.io.FileReader; import org.junit.Test;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory; public class Demo3 { @Test
public void test() throws Exception {
// 通过XMLReaderFactory创建XMLReader对象
XMLReader reader = XMLReaderFactory.createXMLReader();
// 设置事件处理器对象
reader.setContentHandler(new MyDefaultHandler());
// 读取要解析的xml文件
FileReader fileReader = new FileReader(new File(
"src\\sax\\startelement\\web.xml"));
// 指定解析的xml文件
reader.parse(new InputSource(fileReader));
} // 自定义的解析类,通过此类中的startElement了解uri,localName,qName,Attributes的含义
class MyDefaultHandler extends DefaultHandler { @Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
System.out
.println("--------------startElement开始执行--------------------------");
System.out.println("uri:::" + uri);
System.out.println("localName:::" + localName);
System.out.println("qName:::" + qName);
for (int i = 0; i < attributes.getLength(); i++) {
String value = attributes.getValue(i);// 获取属性的value值
System.out.println(attributes.getQName(i) + "-----" + value);
}
System.out
.println("------------------startElement执行完毕---------------------------");
} }
}

3.程序运行的结果如下:

二.我们通过SAXParserFactory、SAXParser、XMLReader完成,步骤如下

1.使用SAXParserFactory创建SAX解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
2.通过SAX解析工厂得到解析器对象
SAXParser sp = spf.newSAXParser();
3.通过解析器对象得到一个XML的读取器
XMLReader xmlReader = sp.getXMLReader();
4.设置读取器的事件处理器
xmlReader.setContentHandler(new BookParserHandler());
5.解析xml文件
xmlReader.parse("book.xml");

说明:如果只是使用SAXParserFactory、SAXParser他们完成只需要如下3步骤

1.获取sax解析器的工厂对象
SAXParserFactory factory = SAXParserFactory.newInstance();
2.通过工厂对象 SAXParser创建解析器对象
SAXParser saxParser = factory.newSAXParser();
3.通过解析saxParser的parse()方法设定解析的文件和自己定义的事件处理器对象
saxParser.parse(new File("src//sax//sida.xml"), new MyDefaultHandler());

案例:解析出"作者"元素标签中的文本内容

1.需要解析的sida.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE 四大名著[
<!ELEMENT 四大名著 (西游记,红楼梦)>
<!ATTLIST 西游记 id ID #IMPLIED>
]>
<四大名著>
<西游记 id="x001">
<作者>吴承恩</作者>
</西游记>
<红楼梦 id="x002">
<作者>曹雪芹</作者>
</红楼梦>
</四大名著>

2.解析测试类和事件处理器类的实现代码

package sax;  

import java.io.File;  

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import org.junit.Test;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; public class SaxTest { @Test
public void test() throws Exception {
// 1.获取sax解析器的工厂对象
SAXParserFactory factory = SAXParserFactory.newInstance();
// 2.通过工厂对象 SAXParser创建解析器对象
SAXParser saxParser = factory.newSAXParser();
// 3.通过解析saxParser的parse()方法设定解析的文件和自己定义的事件处理器对象
saxParser.parse(new File("src//sax//sida.xml"), new MyDefaultHandler()); } // 自己定义的事件处理器
class MyDefaultHandler extends DefaultHandler { // 解析标签开始及结束的的标识符
boolean isOk = false; @Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
// 当解析作者元素开始的时候,设置isOK为true
if ("作者".equals(qName)) {
isOk = true;
}
} @Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
// 当解析的标识符为true时,打印元素的内容
if (isOk) {
System.out.println(new String(ch, start, length));
}
} @Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
// 当解析作者元素的结束的时候,设置isOK为false
if ("作者".equals(qName)) {
isOk = false;
}
} }
}

最后可以看到输出结果为吴承恩、曹雪芹

XML的解析(DOM以及SAX方式)的更多相关文章

  1. JavaEE实战——XML文档DOM、SAX、STAX解析方式详解

    原 JavaEE实战--XML文档DOM.SAX.STAX解析方式详解 2016年06月22日 23:10:35 李春春_ 阅读数:3445 标签: DOMSAXSTAXJAXPXML Pull 更多 ...

  2. 无废话XML--XML解析(DOM和SAX)

    XML处理模式 处理XML有2种方式,DOM和SAX.一般的实际开发中,这2种使用的不多,直接用dom4j来解析XML就好了,包括CRUD等操作都很方便的.这里介绍的DOM和SAX是比较底层的,具体的 ...

  3. XML - 十分钟了解XML结构以及DOM和SAX解析方式

    引言 NOKIA 有句著名的广告语:"科技以人为本".不论什么技术都是为了满足人的生产生活须要而产生的.详细到小小的一个手机.里面蕴含的技术也是浩如烟海.是几千年来人类科技的结晶, ...

  4. XML文件解析DOM解析和SAX解析

    解析一个XML文档有哪些内容解析有:dom和sax两种dom:把整个XML文档放入内存,适合XML随机访问,占用内存资源大sax:事件驱动型的XML解析方式,顺序读取,不用一次装载整个文件,遇到标签会 ...

  5. schema文件及XML文件的DOM和Sax解析

    schema文件 <?xml version="1.0" encoding="UTF-8"?> <schema xmlns="htt ...

  6. Android解析xml文件-采用DOM,PULL,SAX三种方法解析

    解析如下xml文件 <?xml version="1.0" encoding="UTF-8"?> <persons> <perso ...

  7. XML文件的解析—DOM、SAX

    一.DOM 解析 思路:获得Document对象,遍历其中节点获得需要的内容 要点: Document :  DocuemntBuilderFactory --newDocumentBuilder - ...

  8. xml它解析----DOM解析

    DOM模型(documentobject model) •DOM解析器在解析XML文档时,会把文档中的全部元素,依照其出现的层次关系.解析成一个个Node对象(节点). •在dom中.节点之间关系例如 ...

  9. iOS开发中XML的DOM和SAX解析方法

    一.介绍 dom是w3c指定的一套规范标准,核心是按树形结构处理数据,dom解析器读入xml文件并在内存中建立一个结构一模一样的“树”,这树各节点和xml各标记对应,通过操纵此“树”来处理xml中的文 ...

随机推荐

  1. UWP 应用程序内购

    今天来说一下应用程序内购的问题,这里面有坑,给自己做个笔记,也给需要的人提个醒. 我目前的需要是可以允许用户捐赠赞助App的形式内购,最终效果如下 只讲上面的列表部分,下面的就是图片布局啥的,没意思了 ...

  2. 制造测试数据的程序及对拍程序概述(Like CyaRon)

    作为一名OIer,比赛时,对拍是必须的 不对拍,有时可以悔恨终身 首先,对拍的程序 一个是要交的程序 另一个可以是暴力.搜索等,可以比较慢,但是必须正确 下面是C++版对拍程序(C++ & c ...

  3. Taffy Web开发,Python Flask实践详解

    1. 前言 最近为Taffy自动化测试框架写了个页面,主要实现了用例管理.执行,测试报告查看管理.发送邮件及配置等功能. 2. 实现细节 页面使用Python Flask +Bootstrap开发,还 ...

  4. Angular之指令Directive系列

    项目筹备近期开启Angular学习,指令比较难理解所以记录备案,推荐Angualr实战学习视频大漠穷秋 Angular实战 一.指令directive概述 指令可以对元素绑定事件监听或者改变DOM结构 ...

  5. this的取值

    在函数中this到底取何值,是在函数真正被调用执行的时候确定的,函数定义的时候确定不了. 情况1:构造函数 function Foo(){ this.name="王福朋" this ...

  6. Opticks依赖库的下载和编译

    最近下载Opticks的代码编译,用其自带的retrieve-dependencies.bat下载依赖库,总是提示缺少模块. 分析了一下错误原因,根据命令窗的提示,手动下载如下配置文件: https: ...

  7. 时间紧任务重---extjs的学习就这么开始吧

    我们的extjs借助了一个模板引擎--artTemplate,它是一个开源的项目,不多说,给个链接吧:http://aui.github.io/artTemplate/ 直接上代码: <!DOC ...

  8. SOJ--Zig-Zag

    Zig-Zag 在图形图像处理中经常须要将一个二维的图像矩阵转化为一维的向量.二维化一维的过程实际上就是将二维数组的元素按某种顺序构成一维数组. 一种经常使用的序列叫"Zig-Zag&quo ...

  9. iOS 6.0中UIViewController被弃用的一些方法

    郝萌主倾心贡献.尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 概念:de ...

  10. Struts2框架(3)---Action类的3种书写方式

    Action类的3种书写方式 本文主要写有关写Action类的3种书写方式: (1)第一种 Action可以是POJO (简单模型对象)  不需要继承任何父类 也不需要实现任何接口 (2)实现Acti ...