2011-03-02 71 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解析器的教程和示例的链接。在开始编码之前,你最好先看看它们。