SAX解析是一种与PULL解析器类似的XML解析的方法,不同的是,使用PULL解析需要程序员自己获取产生的事件做相应的操作。SAX解析的特点是逐行扫描文档,一边扫描一边解析,这种方式比起一次性将整个XML文件加载到内存中的DOM解析方式也更为安全(不易造成内存溢出),也更为快速有效。同时,SAX还可以在解析文档的任意时刻停止解析。当然,它也有缺点,那就是相对来说,SAX的操作复杂一点。
SAX是事件驱动型XML解析的一个标准接口不会改变 SAX的工作原理简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。
大多数SAX都会产生以下类型的事件:
1.在文档的开始和结束时触发文档处理事件。
2.在文档内每一XML元素接受解析的前后触发元素事件。
3.任何元数据通常由单独的事件处理
4.在处理文档的DTD或Schema时产生DTD或Schema事件。
5.产生错误事件用来通知主机应用程序解析错误。
SAX解析的步骤
1,确定xml文件位置
File f = new File(“xml文件位置”);
2,获取SAXParserFactory 对象
SAXParserFactory fac = SAXParserFactory.newInstance();
3,获取SAXParser解析器对象
SAXParser parser = fac.newSAXParser();
4,开始解析XML
parse(File f, DefaultHandler dh)
f: xml文件
dh: sax解析处理器,SAX解析所有触发的方法都在处理器里面处理
SAX解析XML案例:读取contacts.xml所有的联系人,并封装到集合中
contacts.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<contacts>
<linkman id="1">
<name>乔峰</name>
<email>qf@126.com</email>
<address>襄阳</address>
<group>丐帮</group>
</linkman>
<linkman id="2">
<name>段誉</name>
<email>duanyu@126.com</email>
<address>云南</address>
<group>大理</group>
</linkman>
<linkman id="3">
<name>虚竹</name>
<email>xuzhu@126.com</email>
<address>少林寺</address>
<group>广东</group>
</linkman>
</contacts>
SAX解析过程:
//取出所有xml文件中所有联系人并封装到list集合中
public class SAXParserTest {
@Test//获取SAXParser对象
public void testSAXParser() throws Exception{
File f = new File("E:/MyEclipse/workspace/day02-junit-xml/contacts.xml");
//1、创建SAXParserFactory对象
SAXParserFactory fac = SAXParserFactory.newInstance();
//2.获取SAXParser对象
SAXParser sax = fac.newSAXParser();
//3.解析xml文件
ContactDafultHandler dh = new ContactDafultHandler();
sax.parse(f, dh);
List<Contact> handler = dh.getList();
for (Contact contact : handler) {
System.out.println(contact);
}
}
}
ContactDafultHandler.java
public class ContactDafultHandler extends DefaultHandler{
//list集合
private List<Contact> list = null;
//联系人对象
Contact con ;
//上一个标签的名称
String preTag;
public List<Contact> getList(){
return list;
}
//文档开始时调用
public void startDocument() throws SAXException {
list = new ArrayList<>();//文档开始时创建集合对象
}
//文档结束时调用
public void endDocument() throws SAXException {
}
//元素开始时调用
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if("linkman".equals(qName)){
con = new Contact();
String id = attributes.getValue("id");//得到id
//con.setId(Long.valueOf(id));
con.setId(id);
}
preTag = qName;
}
//元素结束时调用
public void endElement(String uri, String localName, String qName)
throws SAXException {
preTag = null;
}
//读取文本内容时调用
public void characters(char[] ch, int start, int length)
throws SAXException {
String value = new String(ch,start,length);
if(preTag != null){
if("name".equals(preTag)){
con.setName(value);
}
if("email".equals(preTag)){
con.setEmail(value);
}
if("address".equals(preTag)){
con.setAddress(value);
}
if("group".equals(preTag)){
con.setGroup(value);
}
list.add(con);
}
}
}
封装数据:
Contact.java
public class Contact {
private String id;
private String name;
private String email;
private String address;
private String group;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String toString(){
return id +"," + name + "," + email +"," + address +"," +group;
}
}