SAX方式解析XML文件的方法分析

SAX(Simple API for XML)SAX的工作原理简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理方法,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。SAX解析方式适用于大型文档,因为他的解析是逐行进行不用像DOM中那样为所有节点创建对象,这样效率大大提高,所以虽然它不是W3C标准,但它却得到了广泛认可。

这是一个需要解析的XML文件:

<?xml version="1.0" encoding="utf-8"?>
<bookstore>
	<book id="2" type="长篇小说">
			<name>《平凡的世界》</name>
			<author>路遥</author>
			<year>2014</year>
			<price>22</price>
			<outline>《平凡的世界》是中国作家路遥创作的一部百万字的小说。
			</outline>>
	</book>
	<book id="7" type="外文小说">
		<name>"Gone with the Wind"</name>
		<author>Margaret.Mitchell</author>
		<price>99</price>
		<language>English</language>
		<outline>《飘》是美国女作家玛格丽特·米切尔(1900—1949)十年磨一剑的作品,也是惟一的作品。</outline>
	</book>
		<book id="13" type="中文小说">
		<name>《秦腔》</name>
		<author>贾平凹</author>
		<price>99</price>
		<language>汉语</language>
		<outline>《秦腔》以两条线展开,一条线是秦腔戏曲,一条线是农民与土地的关系。</outline>>
	</book>

</bookstore>

如上所示,我们将从首行开始逐一进行解析,SAX解析时会识别开始标签和结束标签,这些用相应的方法进行实现,具体如下:

需要注意的是:DefaultHandler类是SAX2事件处理程序的默认基类。它实现了EntityResolver、DTDHandler、ContentHandler和ErrorHandler这四个接口。包含这四个接口的所有方法,所以我们在编写事件处理程序时,可以不用直接实现这四个接口,而继承该类,然后重写我们需要的方法即可

我们SAX方法解析XML文件时需要一个Handler类来提供解析的方法,里面包含了重写的继承于DefaultHandler类的两种方法,分别有开始和结束的方法

package Handler;

import java.util.ArrayList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import entity.Book;

public class SAXParserHandlerBook extends DefaultHandler{

	int bookIndex = 0;

	Book book = null;

	private ArrayList<Book> bookList = new ArrayList<Book>();

	public ArrayList<Book> getBookList(){
		return bookList;

	}
	//用来标识解析开始和结束
	@Override
	public void startDocument() throws SAXException {

		super.startDocument();

		System.out.println("SAX解析开始");
	}
	@Override
	public void endDocument() throws SAXException {

		super.startDocument();

		System.out.println("SAX解析开始");
	}

	// 用来遍历XML文件的开始标签
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

		super.startElement(uri, localName, qName, attributes);
		//开始解析book节点的属性

		 //注意:这种方法是知道节点名为book且其属性只有id一个属性,只需获取其属性值的情况
		if(qName.equals("book")){
			//在清空之前保存
			bookList.add(book);
			//保证每次运行到这里的时候book都是null以便保存其他子节点的值
			book = null;
			//创建book对象
			book = new Book();
			//这边我们需要一个全局变量来记录遍历进行到哪本书
			bookIndex++;

//			String value = attributes.getValue("id");
                         //【注意这种方法是知道了属性的属性名来获取属性值的简便方法】
//			System.out.println("book的属性值:"+attributes.getValue("id"));

			//在不知道book节点的属性数量以及属性名和属性值的情况下进行解析
			int len = attributes.getLength();

			System.out.println("*************************开始遍历第"+(bookIndex)+"本书*************************");

			for(int i = 0; i < len; i ++){

				System.out.println("第"+(i+1)+"个属性:");

				System.out.println("属性名是:"+ attributes.getQName(i));

				System.out.println("属性值是:"+ attributes.getValue(i));				 
				System.out.println();

				if(attributes.getQName(i).equals("id")){

					book.setId(attributes.getQName(i));

				}else if(attributes.getQName(i).equals("type")){

					book.setId(attributes.getQName(i));
				}
			}
		}

		//获取book节点的所有子节点节点名
		if(qName != "book"){

			System.out.println("节点名:"+qName);	

		}else if(qName.equals("author")){

			book.setAuthor(value);

		}else if(qName.equals("year")){

			book.setYear(value);

		}else if(qName.equals("lauguage")){

			book.setLauguage(value);

		}else if(qName.equals("price")){

			book.setPrice(value);

		}else if(qName.equals("outline")){

			book.setOutline(value);

		}else if(qName.equals("name")){

			book.setName(value);
		}
	}
	//以上部分用switch语句实现代码开起来应该会相对整洁一点,
	String value = null;

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {

		super.characters(ch, start, length);

		value = new String(ch, start, length);

		if(!value.trim().equals("")){	

			System.out.println("节点值:"+value);

			System.out.println();
		}
	}

	// 用来遍历XML结束标签(non-Javadoc)
	 @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
	 
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {

		super.endElement(uri, localName, qName);
		//判断针对一本书是否已经遍历结束
		if(qName.equals("book")){

			System.out.println("===========================结束遍历===========================");
		}
	}

}

Handler类准备好之后我们来编写测试程序看一下解析结果:

package test_XML;

import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;

import Handler.SAXParserHandlerBook;

public class TestSAX {

	public static void main(String[] args) throws ParserConfigurationException, SAXException{

		try {

	// 是创建一个Handler处理类,去逐个分析每一个节点,并且是顺序的

	//1.通过SAXParseFactory的静态方法newInstance()来获取SAXParseFactory的实例对象factory
	SAXParserFactory factory = SAXParserFactory.newInstance();

	//2.通过SAXParserFactory 静态方法NewSAXParser()方法返回一个SAXParser类的实例;
	SAXParserHandlerBook handler = new SAXParserHandlerBook();
	//3.重写startElement、endElement、startDocument、endDocument方法
			/*
			 * 可以将其保存在继承了DefaultHandler类的SAXParserHandler类中
			 * 然后创建SAXParserHandler类的对象并将其传入SAXParser类的对象parser的parser方法;
			 */
		SAXParser parser=factory.newSAXParser();

		parser.parse("book.xml", handler);

		} catch (SAXException e) {

			e.printStackTrace();

		}catch (IOException e) {

			e.printStackTrace();
		}
	} 
}

以下是解析结果:

SAX解析开始

节点名:bookstore

*************************开始遍历第1本书*************************

第1个属性:

属性名是:id

属性值是:2

第2个属性:

属性名是:type

属性值是:长篇小说

节点名:name

节点值:《平凡的世界》

节点名:author

节点值:路遥

节点名:year

节点值:2014

节点名:price

节点值:22

节点名:outline

节点值:《平凡的世界》是中国作家路遥创作的一部百万字的小说。

===========================结束遍历===========================

*************************开始遍历第2本书*************************

第1个属性:

属性名是:id

属性值是:7

第2个属性:

属性名是:type

属性值是:外文小说

节点名:name

节点值:"Gone with the Wind"

节点名:author

节点值:Margaret.Mitchell

节点名:price

节点值:99

节点名:language

节点值:English

节点名:outline

节点值:《飘》是美国女作家玛格丽特·米切尔(1900—1949)十年磨一剑的作品,也是惟一的作品。

===========================结束遍历===========================

*************************开始遍历第3本书*************************

第1个属性:

属性名是:id

属性值是:13

第2个属性:

属性名是:type

属性值是:中文小说

节点名:name

节点值:《秦腔》

节点名:author

节点值:贾平凹

节点名:price

节点值:99

节点名:language

节点值:汉语

节点名:outline

节点值:《秦腔》以两条线展开,一条线是秦腔戏曲,一条线是农民与土地的关系。

节点值:>

===========================结束遍历===========================

DOM(Document Object Model)是表示和处理一个HTML或XML文档的常用方法,DOM的优势是易用性强,使用DOM这种解析方法的时候,将把所有的XML文档信息都存于内存中,遍历操作简单快速。SAX(Simple API for XML)不是W3C的标准,但是对于大型XML文件的解析效率要高与DOM。

时间: 2024-12-29 06:45:44

SAX方式解析XML文件的方法分析的相关文章

SAX方式解析xml文件查看天气

1.SAX方式解析xml文件的步骤: ①创建解析器工厂对象 ②使用当前配置的工厂参数创建SAXParser对象 ③解析xml文件 ④利用DefaultHandler创建事件驱动者 2.对于标签对象进行引用怎么办? ①定义当前解析的标签:private String tagName=null; ②在startElement()方法中赋值tagName:this.tagName=qName; ③在endElement()方法中将tagName赋值为空:this.tagName=null; ④在cha

通过Sax方式解析xml文件

说明:此案例使用的是通过Dom方式解析xml文件这篇文章里的City类和china.xml文件. 1. 因为xml文件有两种格式,一是上面那篇文章里的那种元素节点里只包含属性节点,另一种就是元素节点里包含元素节点和文本节点,于是在china.xml中添加如下代码,以实现两种方式的解析: <city> <cityname>杭州</cityname> <pyName>zhejiang</pyName> <quName>浙江</quN

java中用SAX方式解析xml文件

SAX是Simple API for XML的缩写,它并不是由W3C官方所提出的标准.SAX是一种轻量型的方法,不像DOM解析时,把XML文档全部载入内存中,在PC上操作,Dom还有优势,但在手机中端上则无优势,因为手机内存和硬件都比不上PC强.使用 SAX 是比较安全的,并且 Android 提供了一种传统的 SAX 使用方法,以及一个便捷的 SAX 包装器.SAX采用基于事件驱动的处理方式,它将XML文档转换成一系列的事件,由单独的事件处理器来决定如何处理. 在SAX接口中,事件源是org.

使用SAX方式解析XML文件

package com.pingyijinren.test; import android.util.Log; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * Created by Administrator on 2016/5/19 0019. */ public class ContentHandler extend

通过Pull方式解析xml文件

说明:此案例使用的是通过Sax方式解析xml文件这篇文章里的布局文件.City类和china.xml文件(此文件内包含两种格式),所以只需要完成MainActivity和PullXml就行了,在于展示如何使用Pull方式解析xml文件. 1. PullXml类的主要代码如下: <span style="font-size:14px;">public class PullXml { public List<City> pullXml() { List<Cit

Android程序解析XML文件的方法及使用PULL解析XML案例

一.一般解析XML文件的方法有SAX和DOM.PULL (1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这个层次结构允许开发人员在树中寻找特定信息.分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作.由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的.DOM 以及广义的基于树的处理具有几个优点.首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构

Android系列之网络(四)----SAX方式解析XML数据

?[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4044170.html 联系方式:[email protected] [系列]Android系列之网络:(持续更新) Android系列之网络(一)----使用HttpClient发送HTTP请求(通过get方法获取数据) Android系列之网络(二)----HTTP请求头与响应头 Androi

QT开发(四十三)——SAX方式解析XML

QT开发(四十三)--SAX方式解析XML 一.SAX简介 SAX是Simple API for XML的简写,是一种解析XML文件的替代方法,不是由W3C官方所提出的标准,是一种事件驱动的XML API,接近于底层,速度较快,但不便于随机访问任意节点. SAX解析的核心是事件处理机制,具有占用内存少,效率高等特点. SAX采用事件机制的方式来解析XML文档.使用SAX解析器对XML文档进行解析时,SAX解析器根本不创建任何对象,只是在遇到XML文档的各种标签如文档开始.元素开始.文本.元素结束

通过Dom方式解析xml文件

此项目通过简单的天气情况显示来实现xml文件的解析 1. 搭建环境 1)创建如下图的包.类及文件 2)布局文件的大概样式如下图所示,用到四个TextView控件和一个RadioGroup控件 3)china.xml文件的内容如下 <?xml version="1.0" encoding="UTF-8"?> <china dn="day"> <city cityname="南京" pyName=&q