如何实现两个解析器来解析一个XML?
我在解析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解析???
是的,它可以做到。我假设您使用的是org.xml.sax实现(但基本技术应该可以与任何SAX类型的解析器一起使用)。
使用SAX时,您有一个执行实际解析的XMLParser
,并向其传递一个实现(例如)ContentHandler
接口的对象。
如果要单独处理的项目菜单,你要做的就是用 ContentHandlers
,说ItemContentHandler
和MenuContentHandler
。在每个处理程序中,如果遇到需要由其他处理程序处理的内容,则只需告知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
希望解释它好一点!
哦〜非常感谢。 但我仍然有一些问题, 为什么的startElement()和endElement()在MenuContentHandler和ItemContentHandler将检查不同的localName但拨打相同的处理? – Rebecca 2011-03-02 06:26:07
@Rebecca:如果您想象读者遇到它们时标签的顺序,它会有所帮助。我会编辑我的答案,试图解释... – Mac 2011-03-02 09:58:30
我明白了。 我现在知道流程。感谢您的Mac〜 还有一个问题,如果我需要使用一个对象来存储数据, 我怎么能解析的数据后返回对象? 我的目标是:一级菜单,参数,字符串的内容,ArrayList的
你不需要两个分析器来处理这个使用SAX。您只需要在每个标签开始/结束事件中执行正确的操作;例如推入或弹出堆栈。
或者,使用DOM解析器。
This page有指向SAX和DOM解析器的教程和示例的链接。在开始编码之前,你最好先看看它们。
如何使用DOM,DOM4J或VTD-XML?两个SAX解析器看起来像个坏主意 – 2011-03-02 03:00:26
但是我对dom没有任何想法...... – Rebecca 2011-03-02 03:06:47