java中的DafaultHandler是解析xml檔案時的處理類。雖然很多進行中都是用自定義的handler去解析,但是也是繼承DefaultHandler的。在DefaultHandler中有幾個比較重要的方法。
startDocument() 接收文檔開始的通知。
characters(char[] ch, int start, int length) 接收元素中字元資料的通知。
ch - 字元。
start - 字元數組中的開始位置。
length - 從字元數組中使用的字元數。
endElement(String uri, String localName, String qName)
接收元素結束的通知
endDocument()
接收文檔結束的通知。
startElement(String uri, String localName, String qName, Attributes attributes)
// 接收元素開始的通知
uri - 名稱空間 URI,如果元素沒有任何名稱空間 URI,或者沒有正在執行名稱空間處理,則為空字元串。
localName - 本地名稱(不帶字首),如果沒有正在執行名稱空間處理,則為空字元串。
qName - 限定的名稱(帶有字首),如果限定的名稱不可用,則為空字元串。
attributes - 附加到元素的屬性。如果沒有屬性,則它将是空的 Attributes 對象。
DefaultHandler類是SAX2事件處理程式的預設基類。它繼承了EntityResolver、DTDHandler、ContentHandler和ErrorHandler這四個接口。包含這四個接口的所有方法,是以我們在編寫事件處理程式時,可以不用直接實作這四個接口,而繼承該類,然後重寫我們需要的方法。如下:
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
public class TestDefaultHandler extends DefaultHandler{
public void startDocument() throws SAXException{
System.out.println("開始解析!"); }
public void endDocument() throws SAXException{
System.out.println("解析完成!"); }
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
System.out.println("元素名:"+qName);
}
public void endElement(String uri, String localName, String qName)
throws SAXException{
System.out.println("對"+qName+"的解析完成!");
}
}
詳細過程
一:sax中DefaultHandler解析XML總體過程
startDocument--->具體讀到某個node(非根node和根node)的解析過程 --->endDocument 。
二:DefaultHandler 解析XML 的非根node是按順序的四步(不管目前node是ElementNode[可有屬性]還是TextNode)(非根node本測試程式如 person,name,age):
第一步:startElement. (eg:startElement localName : qName : age)
第二步 : characters (eg:characters in age = 25)
第三步 : endElement (eg: endElement in )
第四步 : characters (eg: characters in null = !)
三:DefaultHandler 解析XML 的根node是按順序的三步(本測試程式中根node為 persons):
第一步:startElement. (eg:startElement localName : qName : persons)
第二步 : characters (eg:characters in persons = !)
第三步 : endElement (eg:endElement in )
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
使用org.sax.helper.DefaultHandler 解析XML ,一般會調用以下六個方法,需要你重寫。
1. 開始解析xml文檔 startDocument
2. 讀到某個節點 startElement-->characters-->endElement-->characters (endElement後會再調用一次characters方法)
3. 解析xml文檔結束 endDocument
------------------------------------------------------------------------------------------------------------
org.sax.helper.DefaultHandler 解析XML 的算法思路(自己了解的)
對每一個非根節點node都要進行兩項檢查:1.檢查是不是ElementNode(用startElement方法) ; 2.是不是TextNode(用characters方法),遇到目前節點結尾時,調用endElement和characters方法。最關鍵的一句話:DefaultHandler會自動解析到下個節點,通過調用startElement方法。并把最新解析到的節點名稱放在startElement(Strng url , Sting localName , String qName , Attributes attributes) 的qName中。
測試代碼
用戶端eclipse讀取伺服器端myeclpse的myhttp工程根目錄下的persons.xml檔案
<?xml version = "1.0" encoding = "UTF-8">
<persons>
<person id="23">
<name>黃老師</name>
<age>26</age>
</person>
<person id="25">
<name>楊老師</name>
<age>28</age>
</person>
</persons>
用戶端程式運作結果
--startDocument--
startElement localName: qName:persons
characters in persons=
!
startElement localName: qName:person
characters in person=
!
startElement localName: qName:name
characters in name=黃老師!
endElement in
characters in null=
!
startElement localName: qName:age
characters in age=26!
endElement in
characters in null=
!
endElement in
characters in null=
!
startElement localName: qName:person
characters in person=
!
startElement localName: qName:name
characters in name=楊老師!
endElement in
characters in null=
!
startElement localName: qName:age
characters in age=28!
endElement in
characters in null=
!
endElement in
characters in null=
!
endElement in
--endDocument--
{name=黃老師, id=23, age=26}
{name=楊老師, id=25, age=28}
1.分析對每一個非根節點都會按順序觸發4個方法,如<age>和<person>;
對于<age>這個節點很直覺可以看到,對于<person>其實也是如此,以person為黃老師為例: 剛開始解析到person節點(即 解析到<person>時),觸發startElement和characters;當周遊完 name 和 age節點 到達</person> 時,觸發了 endElement 和 characters方法
2.而對于根節點<persons>隻觸發前三個方法,而不觸發最後一個characters方法。
因為xml文檔必須包含一個根節點,且隻能包含一個根節點,即本xml的根節點為<persons>具有唯一性,是以當解析遇到</persons>時會知道整個xml文檔已經解析完畢,是以不會觸發characters方法。而是在endElement後直接觸發endDocument方法。