Java使用Sax解析xml文件


使用java的Sax对xml文件进行解析,大致可分为以下几个步骤

1、创建SAXParserFactory实例

2、创建SAXParser实例

3、创建一个继承自DefaultHandler的handler实例

4、使用handler对xml文档进行解析


一、要解析的book.xml文档如下

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
	<book id="156">
		<name>计算机网络</name>
		<author>谢希仁</author>
		<price>39</price>
		<year>2013</year>
	</book>
	<book id="234">
		<name>计算机操作系统</name>
		<author>佚名</author>
		<price>40</price>
		<year>2013</year>
		<edition>第四版</edition>
	</book>
	<book id="367">
		<name>计算机组成原理</name>
		<price>35</price>
		<year>2013</year>
		<edition>第三版</edition>
	</book>
</bookstore>



二、创建SAXParserFactory实例

// 创建SAXParserFactory实例
SAXParserFactory spf = SAXParserFactory.newInstance();


三、创建SAXParser实例

// 创建SAXParser实例
SAXParser parser = spf.newSAXParser();


四、创建DefaultHandler实例(这一步是非常关键的一步)

在介绍DefaultHandler之前,必须对xml的节点和元素进行区分,可以参考http://blog.csdn.net/kingsonyoung/article/details/51985327


DefaultHandler有如下几个接口

 一般前两个方法,开始解析和结束解析文档的不需要做处理外,我们的所有操作都是在解析节点部分,我们调用startElement 开始解析节点,然后调用characters 保存节点的内容,最后调用endElement表示结束对一个节点的访问

        public void startDocument() {
		// 开始解析文档
	}

	public void endDocument() {
		// 文档解析结束
	}

	public void startElement(String uri, String localName, String qName, Attributes attributes) {
		// 开始解析元素节点,注意,此处只是会解析元素节点,即 XML 标签,遇到回车等textNode时不会执行此函数
	}

	public void characters(char[] ch, int start, int length) {
		// 保存节点内容,此处会将回车等textNode的回车符也进行解析
	}

	public void endElement(String uri, String localName, String qName) {
		// 结束解析元素节点
	}




下面是一个解析book.xml的Handler

public class MyHandler extends DefaultHandler {
	int bookIndex = 0;

	/**
	 * 用来遍历开始标签,每走到一个开始标签,如<div>,<book>等不带/的标签,就会调用一次该方法
	 * 
	 * @param uri
	 * @param localName
	 * @param qName
	 *            节点名,即标签名称
	 * @param attributes
	 *            标签的属性
	 */
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		// 调用DefaultHandler类的startElement方法
		super.startElement(uri, localName, qName, attributes);
		// 如果是book开始节点
		if ("book".equals(qName)) {
			bookIndex++;
			// 获取id属性值
			String id = attributes.getValue("id");
			System.out.println("id是:" + id);
		}
		// 如果是book节点下的子节点的开始节点
		else if (!"bookstore".equals(qName)) {
			System.out.print(qName + ":");
		}
	}

	/**
	 * 保存元素节点中的文本节点的文本内容
	 * 
	 * @param ch
	 *            节点中的内容
	 * @param start
	 *            开始标签的位置
	 * @param length
	 *            开始标签的位置到结束标签的位置的长度
	 */
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		super.characters(ch, start, length);
		String value = new String(ch, start, length);
		// 如果节点内容不为空,主要是用来过滤回车符形成的textNode
		if (!value.trim().equals("")) {
			System.out.println(value);
		}
	}

	/**
	 * 用来遍历结束标签
	 */
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		super.endElement(uri, localName, qName);
		// 如果是book节点结束
		if ("book".equals(qName)) {
			System.out.println("--------------结束遍历第" + bookIndex + "本书---------------");
		}

	}

	/**
	 * 用来标识解析开始
	 */
	@Override
	public void startDocument() throws SAXException {
		super.startDocument();
		System.out.println("开始解析xml文件");
	}

	/**
	 * 用来标识解析结束
	 */
	@Override
	public void endDocument() throws SAXException {
		super.endDocument();
		System.out.println("结束解析xml文件");
	}

}

五、使用handler对xml文档进行解析

// 开始解析
parser.parse("book.xml", new MyHandler());


六、运行结果

运行结果如下:

<span style="font-family: Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif;">开始解析xml文件
id是:156
name:计算机网络
author:谢希仁
price:39
year:2013
--------------结束遍历第1本书---------------
id是:234
name:计算机操作系统
author:佚名
price:40
year:2013
edition:第四版
--------------结束遍历第2本书---------------
id是:367
name:计算机组成原理
price:35
year:2013
edition:第三版
--------------结束遍历第3本书---------------
结束解析xml文件</span>


在重写DefaultHandler的startElement,characters接口时需注意一下细节

1、当遇到一个开始元素节点时就会执行一次startElement,这里需要特别注意,元素节点指的是一个xml标签,也就是说遇到开始文本节点不会执行该方法

下面我们把节点名都打印出来,发现的确只是打印出了xml标签,即元素节点。而并没有#text类型的文本节点

	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		// 调用DefaultHandler类的startElement方法
		super.startElement(uri, localName, qName, attributes);
		System.out.println(qName);

	}

打印结果如下:

开始解析xml文件
bookstore
book
name
author
price
year
book
name
author
price
year
edition
book
name
price
year
edition
结束解析xml文件

2、当遇到空格或者换行符时,也会触发characters方法。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值