2011-07-14 70 views
3

我試圖通過簡單地實現org.xml.sax.ContentHandler來解析SAX中的一些第一個XML文檔,我不知道我是否理解流程。對於給定的XML文檔:SAX如何解析文檔?

<?xml version="1.0"?> 
<list> 
    <item> 
     <name>One</name> 
     <description>The number 1, expressed in letters. 
    </item> 
    <item> 
     <name>Two</name> 
     <description>The number 2, expressed in letters. 
    </item> 
</list> 

什麼是在解析器事件所期待的順序?我是否正確地承擔以下事項:

startDocument() 
    startElement() -> "list" 

     startElement() -> "item" 
      startElement() -> "name" 
       characters() (>=1 times) -> "One" 
      endElement() -> "name" 
      startElement() -> "description" 
       characters() (>=1 times) -> "The number 1, expressed in letters." 
      endElement() -> "description" 
     endElement() -> "item" 

     startElement() -> "item" 
      startElement() -> "name" 
       characters() (>=1 times) -> "Two" 
      endElement() -> "name" 
      startElement() -> "description" 
       characters() (>=1 times) -> "The number 2, expressed in letters." 
      endElement() -> "description" 
     endElement() -> "item" 

    endElement() -> "list" 
endDocument() 

這就是它的要點嗎?

另外,什麼是最簡單的方法來解析?目前,在每次調用startElement時,我將保存爲一個私有變量作爲當我在characters調用中解析數據時的當前元素的名稱。有沒有更容易/更好的方法呢?

回答

1

是的,你有它的要義。

SAX是一個非常低級的界面,所以不要指望它很容易。在大多數SAX應用程序中,您可能需要維護堆棧,其中startElement將元素名稱壓入堆棧,endElement將其彈出。如果你沒有處理混合內容,那麼characters()應該附加到與堆棧頂部元素相關聯的StringBuffer,並且當endElement事件發生時,你應該處理StringBuffer中的字符內容。這是因爲字符內容可以分解爲字符()的多個調用,解析器需要的任何方式都可以。

1

不幸的是,SAX狀態機沒有很好的記錄。我並不建議你告訴你一些細節,而是建議你編寫第一個內容處理程序,它只記錄控制檯發生的所有事情,並用不同的輸入進行操作。

但是...是的,你已經掌握了它的要點。至於「最簡單的解析方式」,我很想說「不是SAX」。在使用SAX時,無論如何,您需要實現一個反映文檔結構轉換的狀態機。如果文檔很簡單,那麼您甚至可能不會將其視爲狀態機本身。但是如果你這麼想,那麼我認爲在事件發生時如何儲存你所需要的東西將是相當容易的。

+0

不幸的是,我很確定我會使用SAX,因爲我在使用Restlet的Android上,除非您知道更好的解決方案。 –

+0

您是否嘗試過使用[xstream](http://xstream.codehaus.org/faq.htm) – bbaja42