SAX方式解析XML文档

SAX的特点这里不再赘述,仅用一实例说明SAX解析XML文档的方式与原理

1.SAX常用的接口

   ContentHandler

   该接口封装了一些对事件处理的方法,比如文档的开始和结束、元素的开始和结束、以及元素中的字符数据等事件,当遇到这些事件时,XML解析器会调用ContentHandler中对应的方法来响应该事件。

   ContentHandler接口的方法有以下几种:
    void startDocument()
    void endDocument()
    void startElement(String uri, String localName, String qName, Attributes atts)
    void endElement(String uri, String localName, String qName)
    void characters(char[] ch, int start, int length)
 

   DTDHandler

   用于接收基本的DTD相关事件,仅包括注释和未解析的实体声明部分,报告这些事件需要在startDocument()方法之后和第一个startElement()方法之前

   EntityResolver

   用于解析实体的基本接口,解析器在打开任何外部实体前调用该接口,如果SAX应用程序需要实现自定义处理外部实体,则必须实现此接口。

   ErrorHandler

   SAX错误处理程序的基本接口,如果SAX应用程序需要实现自定义的错误处理,则它必须实现此接口,然后解析器将通过此接口报告所有的错误和警告。

   DefaultHandler

   SAX2程序事件处理程序的默认基类,它实现了上面四个接口,所以我们在编写事件处理程序时,可以直接继承该类,然后重写我们需要的方法。

2.处理实例

   xml文件

<?xml version="1.0" encoding="gb2312"?>
<丛书>
	<书>
		<名>萍踪侠影</名>
		<人>梁羽生</人>
		<价 unit="RMB">100.60</价>
	</书>
	<书>
		<名>岳阳楼记</名>
		<人>范仲淹</人>
		<价 unit="美元">76.8</价>
	</书>	
</丛书>


源代码

package test;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXTest {

	public static void main(String[] args){
		try{
			//创建xml解析处理器
			SAXContentHandler contentHandler = new SAXContentHandler();
			File file = new File("D:\\book.xml");
			//创建SAX解析器
			SAXParserFactory factory = SAXParserFactory.newInstance();
			SAXParser parser = factory.newSAXParser();
			//将xml解析处理器分配给SAX解析器,并对文件进行解析
			parser.parse(file, contentHandler);
			//输出结果
			for(Book book : contentHandler.getBooks()){
				System.out.println(book.toString());
			}
		}catch(FileNotFoundException e){
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

/**
 * 自定义XML解析处理器
 */
class SAXContentHandler extends DefaultHandler{
	private List<Book> books;
	private Book book;
	private String tagName;
	
	public List<Book> getBooks(){
		return this.books;
	}
	
	@Override
	public void startDocument() throws SAXException {
		this.books = new ArrayList<Book>();
		System.out.println("SAX解析文件开始");
	}
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		//有的情况是localName,需要验证
		this.tagName = qName;
		if(this.tagName.equals("书")){
			this.book = new Book();
		}else if(this.tagName.equals("价")){
			this.book.setUnit(attributes.getValue(0));
		}
	}
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		//根据元素名称将字符数据赋给相应的属性
		if(this.tagName != null){
			String data = new String(ch, start, length);
			if(this.tagName.equals("人")){
				this.book.setAuthor(data);
			}else if(this.tagName.equals("名")){
				this.book.setName(data);
			}else if(this.tagName.equals("价")){
				this.book.setPrice(Double.parseDouble(data));
			}
		}
	}
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if(qName.equals("书")){
			this.books.add(this.book);
		}
		//注意将此处设置为null,因为在xml中的空白部分也会被视为一个文本节点,如果不设置为null,当读到空白节点时,如果tagName符合其中一个属性,程序便会将空字符串赋给相应的属性
		this.tagName = null;
	}
	@Override
	public void endDocument() throws SAXException {
		System.out.println("SAX解析文件结束");
	}
	
}

/**
 * 定义实体类
 */
class Book{
	public String author;
	public String name;
	public Double price;
	public String unit;
	
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Double getPrice() {
		return price;
	}
	public void setPrice(Double price) {
		this.price = price;
	}
	public String getUnit() {
		return unit;
	}
	public void setUnit(String unit) {
		this.unit = unit;
	}
	@Override
	public String toString() {
		return "作者:"+this.author+"||书名:"+this.name+"||价格:"+this.price+"("+this.unit+")";
	}
	
}


输出结果

SAX解析文件开始
SAX解析文件结束
作者:梁羽生||书名:萍踪侠影||价格:100.6(RMB)
作者:范仲淹||书名:岳阳楼记||价格:76.8(美元)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值