SAX是Simple API for
XML的缩写,它并不是由W3C官方所提出的标准。SAX是一种轻量型的方法,不像DOM解析时,把XML文档全部载入内存中,在PC上操作,Dom还有
优势,但在手机中端上则无优势,因为手机内存和硬件都比不上PC强。使用 SAX 是比较安全的,并且 Android 提供了一种传统的
SAX 使用方法,以及一个便捷的 SAX
包装器。SAX采用基于事件驱动的处理方式,它将XML文档转换成一系列的事件,由单独的事件处理器来决定如何处理。
在SAX接口中,事件源是org.xml.sax包中的XMLReader,它通过parser()方法来解析XML文档,并根据文档的内容产生事件。而
事件处理器则是org.xml.sax包中的ContentHander、DTDHander、ErrorHandler,以及
EntityResolver这4个接口,它们分别处理事件源在解析XML文档过程中产生的不同种类的事件。在开发中没有必要直接从这4个接口直接继承,
因为org.xml.sax.helper包提供了类DefaultHandler,其继承了这4个接口,在实际开发中直接从
DefaultHandler继承并实现相关函数就可以了。
SAX解析过程分为5个步骤:
1、
/**
* 解析XML时,当开始读取XML文档时
*/
@Override
public void startDocument() throws SAXException {
peoples = new HashSet<People>();
phones = new HashSet<Phone>();
}
2、
/**
* 解析XML时,当开始读到一个元素标签开始时
*/
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
if (name.equals("person")) {
people = new People();
}
if (name.equals("phone")) {
phone = new Phone();
}
currentTag = name;
}
3、
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// 判断当前标签是否有效
if (people != null) {
// //读取标签里面的内容
String value = new String(ch, start, length);
// 如果是Id标签,则读取Id标签的内容设置到Person的ID值上
if ("pid".equalsIgnoreCase(currentTag)) {
people.setPid(value);
} else if ("pname".equalsIgnoreCase(currentTag)) {// name标签
people.setPname(value);
} else if ("page".equalsIgnoreCase(currentTag)) {// age标签
people.setPage(value);
} else if ("psex".equalsIgnoreCase(currentTag)) {// address标签
people.setPsex(value);
} else if ("mPhone".equalsIgnoreCase(currentTag)) {
phone.setmPhone(value);
} else if ("fPhone".equalsIgnoreCase(currentTag)) {
phone.setfPhone(value);
}
}
}
4、
/**
* 解析XML时,当读到结束一个元素标签时
*/
@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
// 如果当前结束的标签名是person的话,代表一个person对象已经读取完毕。将其添加到list后置空
if(people!=null&&name.equals("person")){
people.setPhones(phones);
peoples.add(people);
people = null;
phones = new HashSet<Phone>();
}
if(phone!=null&&name.equals("phone")) {
phones.add(phone);
phone = null;
}
// 将当前标签名置空
currentTag = null;}
5、
/**
* 结束读取XML
*/
@Override
public void endDocument() throws SAXException {}
具体实例:
people.xml
<?xml version="1.0" encoding="UTF-8"?><!--认得信息xml文件-->
<peoples>
<person>
<pid>1</pid>
<pname>张三</pname>
<psex>男</psex>
<page>20</page>
<phone>
<mPhone>11111111111</mPhone>
<fPhone>1234321</fPhone>
</phone>
</person>
<person>
<pid>2</pid>
<pname>王五</pname>
<psex>男</psex>
<page>20</page>
<phone>
<mPhone>12222222222</mPhone>
<fPhone>4445556</fPhone>
</phone>
</person>
<person>
<pid>3</pid>
<pname>李四</pname>
<psex>男</psex>
<page>20</page>
<phone>
<mPhone>33333333332</mPhone>
<fPhone>1234321</fPhone>
</phone>
</person>
</peoples>
People.java实体类
import java.util.Set;public class People {
private String pid;
private String pname;
private String psex;
private String page;
private Set<Phone> phones;
/**
* @return the pid
*/
public String getPid() {
return pid;
}
/**
* @param value the pid to set
*/
public void setPid(String value) {
this.pid = value;
}
/**
* @return the pname
*/
public String getPname() {
return pname;
}
/**
* @param pname the pname to set
*/
public void setPname(String pname) {
this.pname = pname;
}
/**
* @return the psex
*/
public String getPsex() {
return psex;
}
/**
* @param psex the psex to set
*/
public void setPsex(String psex) {
this.psex = psex;
}
/**
* @return the page
*/
public String getPage() {
return page;
}
/**
* @param page the page to set
*/
public void setPage(String page) {
this.page = page;
}
/**
* @return the phones
*/
public Set<Phone> getPhones() {
return phones;
}
/**
* @param phones the phones to set
*/
public void setPhones(Set<Phone> phones) {
this.phones = phones;
}}
Phone.java实体类
public class Phone {private String mPhone;
private String fPhone;
/**
* @return the mPhone
*/
public String getmPhone() {
return mPhone;
}
/**
* @param mPhone the mPhone to set
*/
public void setmPhone(String mPhone) {
this.mPhone = mPhone;
}
/**
* @return the fPhone
*/
public String getfPhone() {
return fPhone;
}
/**
* @param fPhone the fPhone to set
*/
public void setfPhone(String fPhone) {
this.fPhone = fPhone;
}}
SAXXmlService解析类
import java.util.HashSet;
import java.util.Set;import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;public class SAXXmlService extends DefaultHandler{
private People people ;
private Phone phone ;
// //定义一个Person引用
// 此处将XML里的数据封装成People类
private Set<People> peoples ;
private Set<Phone> phones ;
// 定义一个标记变量,标记当前的XML文件被解析到哪个标签
private String currentTag ;/**
* 解析XML时,当开始读取XML文档时
*/
@Override
public void startDocument() throws SAXException {
peoples = new HashSet<People>();
phones = new HashSet<Phone>();
}@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// 判断当前标签是否有效
if (people != null) {
// //读取标签里面的内容
String value = new String(ch, start, length);
// 如果是Id标签,则读取Id标签的内容设置到Person的ID值上
if ("pid".equalsIgnoreCase(currentTag)) {
people.setPid(value);
} else if ("pname".equalsIgnoreCase(currentTag)) {// name标签
people.setPname(value);
} else if ("page".equalsIgnoreCase(currentTag)) {// age标签
people.setPage(value);
} else if ("psex".equalsIgnoreCase(currentTag)) {// address标签
people.setPsex(value);
} else if ("mPhone".equalsIgnoreCase(currentTag)) {
phone.setmPhone(value);
} else if ("fPhone".equalsIgnoreCase(currentTag)) {
phone.setfPhone(value);
}
}
}/**
* 解析XML时,当开始读到一个元素标签开始时
*/
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
if (name.equals("person")) {
people = new People();
}
if (name.equals("phone")) {
phone = new Phone();
}
currentTag = name;
}/**
* 解析XML时,当读到结束一个元素标签时
*/
@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
// 如果当前结束的标签名是person的话,代表一个person对象已经读取完毕。将其添加到list后置空
if(people!=null&&name.equals("person")){
people.setPhones(phones);
peoples.add(people);
people = null;
phones = new HashSet<Phone>();
}
if(phone!=null&&name.equals("phone")) {
phones.add(phone);
phone = null;
}
// 将当前标签名置空
currentTag = null;}
/**
* 结束读取XML
*/
@Override
public void endDocument() throws SAXException {}
/**
* @return the peoples
*/
public Set<People> getPeoples() {
return peoples;
}/**
* @return the phones
*/
public Set<Phone> getPhones() {
return phones;
}/**
* @param phones the phones to set
*/
public void setPhones(Set<Phone> phones) {
this.phones = phones;
}}
SAXTest测试类
import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;import javax.ejb.Handle;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;import org.xml.sax.SAXException;
public class SAXTest {
public static void main(String[] args) throws Exception {
Set<People> peoples = new SAXTest().parseXMLFile();
System.out.println(peoples);
System.out.println(peoples.size());
for(People people:peoples){
System.out.println(people.getPname());
System.out.println(people.getPsex());
System.out.println(people.getPage());Set<Phone> phones = people.getPhones();
for(Phone phone:phones){
System.out.println(phone.getmPhone());
System.out.println(phone.getfPhone());
}
}}
/**
*
* 解析文档
*/
private Set<People> parseXMLFile() throws Exception{
//创建解析器工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//创建解析器
SAXParser saxParse = factory.newSAXParser();
//创建输入流
InputStream is = SAXTest.class.getClassLoader().getResourceAsStream("people.xml");//得到sax解析类
SAXXmlService handle = new SAXXmlService();
//开始解析
saxParse.parse(is, handle);
is.close();
return handle.getPeoples();}
}
执行结果:
[[email protected], [email protected], [email protected]]
3
people3
name======李四
sex======男
age======20
手机======33333333332
座机======1234321
people1
name======张三
sex======男
age======20
手机======11111111111
座机======1234321
people2
name======王五
sex======男
age======20
手机======12222222222
座机======4445556