2011-03-02 111 views
2

我在解析xml時遇到了問題。 XML格式是這樣的,如何實現兩個解析器來解析一個XML?

<root> 
    <menu> 
     <items> 
      <menu> 
       <items>    
        <menu> 
         <content/> 
        </menu> 
        <menu> 
         <content/> 
        </menu> 
        <menu> 
         <content/> 
        </menu> 
       <items>    
      </menu> 
      <menu> 
       <items>    
        <menu> 
         <content/> 
        </menu> 
        <menu> 
         <content/> 
        </menu> 
        <menu> 
         <items>    
         <menu> 
          <content/> 
         </menu> 
         <menu> 
          <content/> 
         </menu> 
         <menu> 
          <content/> 
         </menu> 
         <items> 
        </menu> 
       <items> 
      </menu> 
     </items> 
    </menu> 
</root> 

我不知道有多深有關XML ...... 我可以用兩個SAX解析器來解析這個XML,而我讀出,調用MenuItemParser到解析,而我讀的是,調用ItemsParser解析???

+1

如何使用DOM,DOM4J或VTD-XML?兩個SAX解析器看起來像個壞主意 – 2011-03-02 03:00:26

+0

但是我對dom沒有任何想法...... – Rebecca 2011-03-02 03:06:47

回答

3

是的,它可以做到。我假設您使用的是org.xml.sax實現(但基本技術應該可以與任何SAX類型的解析器一起使用)。

使用SAX時,您有一個執行實際解析的XMLParser,並向其傳遞一個實現(例如)ContentHandler接口的對象。

如果要單獨處理的項目菜單,你要做的就是用 ContentHandlers,說ItemContentHandlerMenuContentHandler。在每個處理程序中,如果遇到需要由其他處理程序處理的內容,則只需告知XMLReader即可使用其他處理程序。

如果你想包含在<menu>標籤一切由MenuContentHandler辦理,裏面的一切<items>標籤由ItemContentHandler處理,你會做類似如下:

class MenuContentHandler implements ContentHandler 
{ 
    public XMLReader reader; 
    public ItemContentHandler itemHandler; 

    ... 
    public void startElement(java.lang.String uri, java.lang.String localName, 
     java.lang.String qName, Attributes atts) 
    { 
     if (localName.equals("items")) 
      reader.setContentHandler(itemHandler); // Point 1 
    } 
    ... 
    public void endElement(java.lang.String uri, java.lang.String localName, 
     java.lang.String qName) 
    { 
     if (localName.equals("menu")) 
      reader.setContentHandler(itemHandler); // Point 2 
    } 
    ... 
} 

class ItemContentHandler implements ContentHandler 
{ 
    public XMLReader reader; 
    public MenuContentHandler menuHandler; 

    ... 
    public void startElement(java.lang.String uri, java.lang.String localName, 
     java.lang.String qName, Attributes atts) 
    { 
     if (localName.equals("menu")) 
      reader.setContentHandler(menuHandler); // Point 3 
    } 
    ... 
    public void endElement(java.lang.String uri, java.lang.String localName, 
     java.lang.String qName) 
    { 
     if (localName.equals("items")) 
      reader.setContentHandler(menuHandler); // Point 4 
    } 
    ... 
} 
... 
void doParsing () 
{ 
    XMLReader reader = XMLReaderFactory.createXMLReader(); 
    MenuContentHandler menuHandler = new MenuContentHandler(reader); 
    ItemContentHandler itemHandler = new ItemContentHandler(reader); 

    menuHandler.itemHandler = itemHandler; 
    itemHandler.menuHandler = menuHandler; 

    reader.setContentHandler(menuhandler); 
    reader.parse (/*your document*/); 
} 

不是最好的代碼在世界範圍內,但希望它能得到重點......如果您需要更多,請讓我知道。

編輯:是如何工作的 - 想象XML的下面的代碼片段:

1 <menu> 
2  <items> 
3   <menu> 
4    <content/> 
5   </menu> 
6   <menu> 
7    <content/> 
8   </menu> 
9   <menu> 
10    <content/> 
11   </menu> 
12  </items> 
13 </menu> 

假設當讀者在這個片段開始時,ItemContentHandler是在控制。

它遇到的第一件事是第1行的<menu>標籤。這表示菜單項的開始,因此我們切換到MenuContentHandler(這標記爲上面的「第3點」),以便我們可以讀取菜單元素。

在這種情況下,元素中的第一個元素實際上是一個元素元素(第2行),因此我們改變爲ItemContentHandler,以便它可以處理item元素的內容(這次點1)。

第3行是第1行的重複,所以我們再次切換到第3點的MenuContentHandler以檢查菜單元素的內容。

下一個元素是第4行的<content/>標記,由MenuContentHandler(我在最後一段中提到,目前負責)處理。

在第5行,菜單用</menu>標籤關閉。現在,由於所有菜單元素都包含在項目元素中,因此我們知道現在必須位於菜單的包含項目元素中。因此,我們切換到ItemContentHandler。這是點2

第6行開始一個新的菜單項,並因此通過11.

線12結束的物品處理元件相同的方式線1和3等了線7,並且通過第5,8和11行的等價邏輯,我們知道我們現在必須位於包含item元素的菜單元素中。所以,我們換成MenuContentHandler(第4點)。

12號線是一個菜單項的末尾,因此被視爲同線5,8和11

希望解釋它好一點!

+0

哦〜非常感謝。 但我仍然有一些問題, 爲什麼的startElement()和endElement()在MenuContentHandler和ItemContentHandler將檢查不同的localName但撥打相同的處理? – Rebecca 2011-03-02 06:26:07

+0

@Rebecca:如果您想象讀者遇到它們時標籤的順序,它會有所幫助。我會編輯我的答案,試圖解釋... – Mac 2011-03-02 09:58:30

+0

我明白了。 我現在知道流程。感謝您的Mac〜 還有一個問題,如果我需要使用一個對象來存儲數據, 我怎麼能解析的數據後返回對象? 我的目標是:一級菜單,參數,字符串的內容,ArrayList的

項目 – Rebecca 2011-03-02 11:01:18

0

你不需要兩個分析器來處理這個使用SAX。您只需要在每個標籤開始/結束事件中執行正確的操作;例如推入或彈出堆棧。

或者,使用DOM解析器。

This page有指向SAX和DOM解析器的教程和示例的鏈接。在開始編碼之前,你最好先看看它們。