startDocument()
當(dāng)遇到文檔的開(kāi)頭的時(shí)候,調(diào)用這個(gè)方法,可以在其中做一些預(yù)處理的工作。
endDocument()
和上面的方法相對(duì)應(yīng),當(dāng)文檔結(jié)束的時(shí)候,調(diào)用這個(gè)方法,可以在其中做一些善后的工作。
startElement(String namespaceURI, String localName, String qName, Attributes atts)
當(dāng)讀到一個(gè)開(kāi)始標(biāo)簽的時(shí)候,會(huì)觸發(fā)這個(gè)方法。namespaceURI就是命名空間,localName是不帶命名空間前綴的標(biāo)簽名,qName是帶命名空間前綴的標(biāo)簽名。通過(guò)atts可以得到所有的屬性名和相應(yīng)的值。要注意的是SAX中一個(gè)重要的特點(diǎn)就是它的流式處理,當(dāng)遇到一個(gè)標(biāo)簽的時(shí)候,它并不會(huì)紀(jì)錄下以前所碰到的標(biāo)簽,也就是說(shuō),在startElement()方法中,所有你所知道的信息,就是標(biāo)簽的名字和屬性,至于標(biāo)簽的嵌套結(jié)構(gòu),上層標(biāo)簽的名字,是否有子元屬等等其它與結(jié)構(gòu)相關(guān)的信息,都是不得而知的,都需要你的程序來(lái)完成。這使得SAX在編程處理上沒(méi)有DOM來(lái)得那么方便。
endElement(String uri, String localName, String name)
這個(gè)方法和上面的方法相對(duì)應(yīng),在遇到結(jié)束標(biāo)簽的時(shí)候,調(diào)用這個(gè)方法。
characters(char[] ch, int start, int length)
這個(gè)方法用來(lái)處理在XML文件中讀到的內(nèi)容,第一個(gè)參數(shù)用于存放文件的內(nèi)容,后面兩個(gè)參數(shù)是讀到的字符串在這個(gè)數(shù)組中的起始位置和長(zhǎng)度,使用new String(ch,start,length)就可以獲取內(nèi)容。
只要為SAX提供實(shí)現(xiàn)ContentHandler接口的類,那么該類就可以得到通知事件(實(shí)際上就是SAX調(diào)用了該類中的回調(diào)方法)。因?yàn)镃ontentHandler是一個(gè)接口,在使用的時(shí)候可能會(huì)有些不方便,因此,SAX還為其制定了一個(gè)Helper類:DefaultHandler,它實(shí)現(xiàn)了這個(gè)接口,但是其所有的方法體都為空,在實(shí)現(xiàn)的時(shí)候,你只需要繼承這個(gè)類,然后重載相應(yīng)的方法即可。使用SAX解析itcast.xml的代碼如下:
public static List
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser(); //創(chuàng)建解析器
//設(shè)置解析器的相關(guān)特性,http://xml.org/sax/features/namespaces = true 表示開(kāi)啟命名空間特性
saxParser.setProperty(“http://xml.org/sax/features/namespaces”,true);
XMLContentHandler handler = new XMLContentHandler();
saxParser.parse(inStream, handler);
inStream.close();
return handler.getPersons();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
SAX 支持已內(nèi)置到JDK1.5中,你無(wú)需添加任何的jar文件。XMLContentHandler的代碼:
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import cn.itcast.xml.domain.Person;
public class XMLContentHandler extends DefaultHandler {
private List
private Person currentPerson;
private String tagName = null;//當(dāng)前解析的元素標(biāo)簽
public List
return persons;
}
/*
* 接收文檔的開(kāi)始的通知。
*/
@Override public void startDocument() throws SAXException {
persons = new ArrayList
}
/*
* 接收字符數(shù)據(jù)的通知。
*/
@Override public void characters(char[] ch, int start, int length) throws SAXException {
if(tagName!=null){
String data = new String(ch, start, length);
if(tagName.equals(“name”)){
this.currentPerson.setName(data);
}else if(tagName.equals(“age”)){
this.currentPerson.setAge(Short.parseShort(data));
}
}
}
/*
* 接收元素開(kāi)始的通知。
* 參數(shù)意義如下:
* namespaceURI:元素的命名空間
* localName :元素的本地名稱(不帶前綴)
* qName :元素的限定名(帶前綴)
* atts :元素的屬性集合
*/
@Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if(localName.equals(“person”)){
currentPerson = new Person();
currentPerson.setId(Integer.parseInt(atts.getValue(“id”)));
}
this.tagName = localName;
}
/*
* 接收文檔的結(jié)尾的通知。
* 參數(shù)意義如下:
* uri :元素的命名空間
* localName :元素的本地名稱(不帶前綴)
* name :元素的限定名(帶前綴)
*
*/
@Override public void endElement(String uri, String localName, String name) throws SAXException {
if(localName.equals(“person”)){
persons.add(currentPerson);
currentPerson = null;
}
this.tagName = null;
}
}