天天看點

JAVA中DefaultHandler

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方法。