1. 简介
dom解析功能强大,可增删改查,操作时会将xml文档读到内存,因此适用于小文档;
sax解析是从头到尾逐行逐个元素解析,修改较为不便,但适用于只读的大文档;
sax采用事件驱动的方式解析xml。套用网友的解释:如同在电影院看电影一样,从头到尾看一遍,不能回退(dom可来来回回读取),在看电影的过程中,每遇到一个情节,都会调用大脑去接收处理这些信息。sax也是相同的原理,每遇到一个元素节点,都会调用相应的方法来处理。在sax的解析过程中,读取到文档开头、文档结尾,元素的开头和元素结尾都会调用相应方法,我们可以在这些方法中进行相应事件处理。
对应方法:
<code>public void startdocument() throws saxexception {</code>
<code>}</code>
<code>public void enddocument() throws saxexception {</code>
<code>public void startelement(string uri, string localname, string qname, attributes attributes) throws saxexception {</code>
<code>public void endelement(string uri, string localname, string qname) throws saxexception {</code>
我们还需一个方法来处理元素节点中间的文本节点(我们常误以为元素节点的文本值)
<code>public void characters(char[] ch, int start, int length) throws saxexception {</code>
2. 解析
解析步骤:
(1)通过saxparserfactory的静态方法newinstance()方法获取saxparserfactory实例对象factory
<code>saxparserfactory factory = saxparserfactory.newinstance();</code>
(2)通过saxparserfactory实例的newsaxparser()方法返回saxparser实例parser
<code>saxparser parser = factory.newsaxparser();</code>
(3)创建一个类继承defaulthandler,重写其中的一些方法进行业务处理
<code>package com.qunar.handler;</code>
<code>import org.xml.sax.attributes;</code>
<code>import org.xml.sax.saxexception;</code>
<code>import org.xml.sax.helpers.defaulthandler;</code>
<code>public class saxparserhandler extends defaulthandler{</code>
<code></code>
<code>// 用来标示解析开始</code>
<code>@override</code>
<code>// 用来标示解析结束</code>
<code>// 用来遍历xml文件的开始标签</code>
<code>super.startelement(uri, localname, qname, attributes);</code>
<code>// 用来遍历xml文件的结束标签</code>
<code>super.endelement(uri, localname, qname);</code>
<code>super.characters(ch, start, length);</code>
(4)创建handler类对象实例
<code>// 定义saxparserhandler对象</code>
<code>saxparserhandler handler = new saxparserhandler();</code>
(5)解析xml文档
<code>saxparser.parse(path, handler);</code>
以下代码均使用本xml文档:
<code><?xml version="1.0" encoding="utf-8"?><bookstore></code>
<code><book category="java"></code>
<code><title lang="chi">java多线程编程核心技术</title></code>
<code><author>高洪岩</author></code>
<code><year>2015</year></code>
<code><price>69.00</price></code>
<code></book></code>
<code><book category="c++"></code>
<code><title lang="en">effective c++: 55 specific ways to improve your programs and designs</title></code>
<code><author>scott meyers</author></code>
<code><year>2006</year></code>
<code><price>58.00</price></code>
<code><book category="web"></code>
<code><title lang="en">learning xml</title></code>
<code><author>erik t. ray</author></code>
<code><year>2016</year></code>
<code><price>39.95</price></code>
<code></bookstore></code>
3. 具体实例:
<code> </code>
<code>private int bookindex = 0;</code>
<code>system.out.println("sax解析开始...");</code>
<code>system.out.println("sax解析结束...");</code>
<code>// 调用defaulthandler类的startelement方法</code>
<code>// 开始解析book元素节点</code>
<code>if(qname.equals("book")){</code>
<code>++ bookindex;</code>
<code>system.out.println("开始解析第" + bookindex + "本书...");</code>
<code>// 已知book元素节点下的属性名称,根据属性名称获取属性值</code>
<code>/*string value = attributes.getvalue("category");</code>
<code>system.out.println("value->"+value);*/</code>
<code>// 不知道book元素节点下的属性名称以及个数</code>
<code>int size = attributes.getlength();</code>
<code>for(int i = 0;i < size;++i){</code>
<code>system.out.println(attributes.getqname(i) + ":" + attributes.getvalue(i));</code>
<code>}//for</code>
<code>}//if</code>
<code>else if(!qname.equals("bookstore")){</code>
<code>system.out.print(qname + ":");</code>
<code>}//else</code>
<code>// 判断一本书是否解析完</code>
<code>system.out.println("结束解析第" + bookindex + "本书...");</code>
<code>string text = new string(ch, start, length);</code>
<code>if(!text.trim().equals("")){</code>
<code>system.out.println(text);</code>
<code>package com.qunar.xml;</code>
<code>import java.io.ioexception;</code>
<code>import javax.xml.parsers.parserconfigurationexception;</code>
<code>import javax.xml.parsers.saxparser;</code>
<code>import javax.xml.parsers.saxparserfactory;</code>
<code>import com.qunar.handler.saxparserhandler;</code>
<code>/**</code>
<code>* sax方式解析xml文档</code>
<code>* @author sjf0115</code>
<code>*</code>
<code>*/</code>
<code>public class saxxmlcode {</code>
<code>public static void main(string[] args) {</code>
<code>string path = "d:\\bookstore.xml";</code>
<code>try {</code>
<code>// 通过saxparserfactory的静态方法newinstance()方法获取saxparserfactory实例对象factory</code>
<code>// 通过saxparserfactory实例的newsaxparser()方法返回saxparser实例parser</code>
<code>saxparser saxparser = factory.newsaxparser();</code>
<code>// 解析xml文档</code>
<code>} catch (parserconfigurationexception e) {</code>
<code>e.printstacktrace();</code>
<code>} catch (saxexception e) {</code>
<code>} catch (ioexception e) {</code>
运行结果:
sax解析开始...
开始解析第1本书...
category:java
title:java多线程编程核心技术
author:高洪岩
year:2015
price:69.00
结束解析第1本书...
开始解析第2本书...
category:c++
title:effective c++: 55 specific ways to improve your programs and designs
author:scott meyers
year:2006
price:58.00
结束解析第2本书...
开始解析第3本书...
category:web
title:learning xml
author:erik t. ray
year:2016
price:39.95
结束解析第3本书...
sax解析结束...
4. 解析并储存于对象中
<code>package com.qunar.bean;</code>
<code>* book实体类</code>
<code>public class book {</code>
<code>private string category;</code>
<code>private string title;</code>
<code>private string author;</code>
<code>private string year;</code>
<code>private string price;</code>
<code>private string lang;</code>
<code>public string getcategory() {</code>
<code>return category;</code>
<code>public void setcategory(string category) {</code>
<code>this.category = category;</code>
<code>public string gettitle() {</code>
<code>return title;</code>
<code>public void settitle(string title) {</code>
<code>this.title = title;</code>
<code>public string getauthor() {</code>
<code>return author;</code>
<code>public void setauthor(string author) {</code>
<code>this.author = author;</code>
<code>public string getyear() {</code>
<code>return year;</code>
<code>public void setyear(string year) {</code>
<code>this.year = year;</code>
<code>public string getprice() {</code>
<code>return price;</code>
<code>public void setprice(string price) {</code>
<code>this.price = price;</code>
<code>public string getlang() {</code>
<code>return lang;</code>
<code>public void setlang(string lang) {</code>
<code>this.lang = lang;</code>
<code>public string tostring() {</code>
<code>return "category:" + category + " lang:" + lang + " title:" + title + " author:" + author + " year:" + year + " price:" + price;</code>
<code>import java.util.arraylist;</code>
<code>import java.util.list;</code>
<code>import com.qunar.bean.book;</code>
<code>private book book;</code>
<code>// 节点文本内容</code>
<code>private string text;</code>
<code>private list<book> booklist = new arraylist<book>();</code>
<code>public list<book> getbooklist() {</code>
<code>return booklist;</code>
<code>// 创建一个book对象</code>
<code>book = new book();</code>
<code>string attr = attributes.getqname(i);</code>
<code>// 属性category</code>
<code>if(attr.equals("category")){</code>
<code>book.setcategory(attributes.getvalue(i));</code>
<code>// 用于遍历title节点中的属性</code>
<code>else if(qname.equals("title")){</code>
<code>if(attr.equals("lang")){</code>
<code>book.setlang(attributes.getvalue(i));</code>
<code>booklist.add(book);</code>
<code>book = null;</code>
<code>book.settitle(text);</code>
<code>else if(qname.equals("author")){</code>
<code>book.setauthor(text);</code>
<code>else if(qname.equals("year")){</code>
<code>book.setyear(text);</code>
<code>else if(qname.equals("price")){</code>
<code>book.setprice(text);</code>
<code>// 文本值</code>
<code>text = new string(ch, start, length);</code>
<code>// 得到遍历结果</code>
<code>list<book> booklist = handler.getbooklist();</code>
<code>system.out.println("遍历结果:");</code>
<code>for (book book : booklist) {</code>
<code>system.out.println(book);</code>
遍历结果:
category:java lang:chi title:java多线程编程核心技术 author:高洪岩 year:2015 price:69.00
category:c++ lang:en title:effective c++: 55 specific ways to improve your programs and designs author:scott meyers year:2006 price:58.00
category:web lang:en title:learning xml author:erik t. ray year:2016 price:39.95