--------------------------------------------XML之SAX解析XML------------------------------------------
一,前言
SAX是针对DOM解析XML内存占用大,查找速度慢的缺点而出现的解决方案。SAX解析器对XML文档解析会从XML文档开始位置起进行解析,同时根据已经定义好的事件处理器,来解决当前所解析的部分(元素、属性或是元素的内容)是否有必要记录并存储。下面首先看看一个使用SAX解析数据的程序,代码如下。
1,SaxXML.java
package com.test;
import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class SaxXML {
public static void main(String[] args) {
//创建解析的XML 文档对象
File xmlFile=new File("music.xml");
//创建一个SAXParserFactory 对象 ,通过单例模式创建
SAXParserFactory factory=SAXParserFactory.newInstance();
try {
//创建SAXParser 对象
SAXParser parser=factory.newSAXParser();
// 解析文件,定义解析时的事件处理
parser.parse(xmlFile, new MySaxHandler());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
2,MySaxHandler.java
package com.test;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class MySaxHandler extends DefaultHandler {
static DateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 格式化内容
private String content;
/*
* 事件发生时元素中的字符
* (non-Javadoc)
* @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
content=new String(ch,start,length);
}
/**
* 当解析到元素的结束标签时发生
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
if("name".equals(qName)){
System.out.println("歌名:"+content);
}else if("author".equals(qName)){
System.out.println("歌手:"+content);
}else if("county".equals(qName)){
System.out.println("国家:"+content);
}else if("date".equals(qName)){
System.out.println("发布日期:"+content);
}
}
/**
* 当解析到元素大的开始标签时发生
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
if("music".equals(qName)){
System.out.println("\r\n找到一首歌.所属分类:"+attributes.getValue("category")+".");
}
}
}
3,music.xml
<?xml version="1.0" encoding="UTF-8"?>
<musics>
<music category="摇滚">
<name>江南style</name>
<author>PSY</author>
<county>韩国</county>
<date>20121205</date>
</music>
<music category="摇滚">
<name>航母style</name>
<author>网民</author>
<county>中国</county>
<date>20121205</date>
</music>
</musics>
4,附图
程序运行后的效果与DOM解析的效果完全相同。两种方式虽然都达到了同样的目的,但其底层的实现却是完全不同的,通过以上的程序,可以总结出使用SAX解析时,需要注意的问题:
(1),首先要通过以下三个步骤解析XML文件。
//创建一个SAXParserFactory 对象 ,通过单例模式创建
SAXParserFactory factory=SAXParserFactory.newInstance();
//创建SAXParser 对象
SAXParser parser=factory.newSAXParser();
// 解析文件,定义解析时的事件处理
parser.parse(xmlFile, new MySaxHandler());
(2),在解析XML数据时,要创建一个解析时的监听器对象,这里通过继承DefaultHandle类。
DefaultHandle的常用方法:
1,void characters(char[] ch, int start, int length);收到元素中字符数据的通知。
2,void endElement() || endElement(String uri, String localName, String qName);收到元素结束的通知。
3,void startElement() || startElement(String uri, String localName, String qName, Attributes attributes);收到 文档开始的通知。