(一)SAX解析是什么?
SAX(simple API for XML)是一种XML解析的替代方法。相比于DOM,SAX是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。而且相比于DOM,SAX可以在解析文档的任意时刻停止解析,但任何事物都有其相反的一面,对于SAX来说就是操作复杂。
(二)SAX解析和DOM解析的区别?
DOM解析 | SAX解析 |
---|---|
一次性加载xml文档,不适合大容量的文件读取 | 加载一点,读取一点,处理一点。适合大容量文件的读取 |
DOM解析任意读取任何位置的数据,甚至往回读 | SAX解析只能从上往下,按顺序读取,不能往回读 |
DOM解析可以任意进行增删改查 | SAX解析只能读取 |
DOM解析面向对象的编程方法(Node,Element,Attribute),Java开发者编码比较简单。 | SAX解析基于事件的编程方法。java开发编码相对复杂。 |
(三)SAX方法解析XML的步骤
- 通过SAXParserFactory的静态newInstence()方法 获取SAXParserFactory实例factory
- 通过SAXParserFactory实例的newSAXParser()方法 返回SAXParser实例parser
- 创建一个类继承DefaultHandler,重写其中的一些方法进行业务处理并创建这个类的实例handler
- 将xml文件地址和handler实例加载到SAXParser实例:parser.parse(“books.xml”,handler);
注:SAX解析的时候,其过程是:startElement-characters-endElement ; characters解析完一个属性,到endElement结束,然后又开始解析下一个属性,到endElement结束,以此类推,最后解析完全部属性,又回到startElement开始解析下一个节点。
(四)SAX解析Java代码实现
1.测试主程序:
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 com.zzh.handle.SAXParserHandler;
public class test {
public static void main(String[] args) {
//获取一个SAXParserFactory实例
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
//通过factory对象获取一个SAXParser实例
SAXParser parser = factory.newSAXParser();
//创建SAXParserHandle对象
SAXParserHandler handler = new SAXParserHandler();
parser.parse("books.xml", handler);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
2.SAXParserHandler类:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXParserHandler extends DefaultHandler {
int bookIndex = 0; //book节点索引值
/**
* 用来遍历xml文件的开始标签
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
super.startElement(uri, localName, qName, attributes);
if ("book".equals(qName)){
bookIndex ++;
System.out.println("======开始遍历第" + bookIndex + "本书的内容======");
//已知book元素下属性的名称,根据属性名称获取属性值
// String value = attributes.getValue("id");
// System.out.println("book的属性值是:" + value);
//不知道book元素下属性的名称,如何获取属性名以及属性值
int num = attributes.getLength();
for(int i=0;i<num;i++){
System.out.print("book元素的第" + (i + 1) + "个属性名是:"
+attributes.getQName(i));
System.out.println("---属性值是:" + attributes.getQName(i));
}
}else if(!"book".equals(qName) && !"bookstore".equals(qName)){
System.out.print("节点名是:" + qName);
}
}
/**
* 用来遍历xml文件的结束标签
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
if("book".equals(qName)){
System.out.println("======结束遍历第" + bookIndex + "本书的内容======");
}
}
/**
* 获取节点值
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
String value = new String(ch,start,length);
//除去Text类型的节点
if(!"".equals(value.trim())){
System.out.println("---节点值是:" + value);
}
}
/**
* 用来标识标志解析开始
*/
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
super.startDocument();
System.out.println("====SAX解析开始====");
}
/**
* 用来标识标志解析结束
*/
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
super.endDocument();
System.out.println("====SAX解析结束====");
}
}
3.程序运行结果展示:
4.books.xml文件源码:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book id="1">
<name>冰与火之歌</name>
<author>乔治马丁</author>
<year>2014</year>
<price>88</price>
</book>
<book id="2">
<name>安徒生童话</name>
<year>2004</year>
<price>77</price>
<language>English</language>
</book>
</bookstore>