解析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来解析???
答案 0 :(得分:3)
是的,可以做到。我假设您正在使用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
(这在上面标记为“Point 3”)所以我们可以读取菜单元素的内容。
在这种情况下,元素中的第一件事实际上是一个item元素(第2行),所以我们以同样的方式更改为ItemContentHandler
,以便它可以处理item元素的内容(这时间,在第1点)。
第3行是第1行的重复,所以我们再次切换到第3点的MenuContentHandler
来检查菜单元素的内容。
下一个元素是第4行的<content/>
标记,由MenuContentHandler
处理(我在上一段中提到过,目前正在处理)。
在第5行,菜单以</menu>
标记结束。现在,由于所有菜单元素都包含在item元素中,因此我们知道现在必须在菜单中包含item元素。因此,我们切换到ItemContentHandler
。这是第2点。
第6行启动一个新的菜单项,因此与第1行和第3行的处理方式相同。对于第7行到第11行,依此类推。
第12行结束items元素,并且通过与第5,8和11行等效的逻辑,我们知道现在必须在包含item元素的menu元素中。所以,我们改为MenuContentHandler
(第4点)。
第12行是菜单项的结尾,因此与第5,8和11行的处理方式相同。
希望能更好地解释一下!
答案 1 :(得分:0)
使用SAX不需要两个解析器来处理它。您只需要在每个标签开始/结束事件中执行正确的操作;例如推或弹出一堆。
或者,使用DOM解析器。
This page包含指向SAX和DOM解析器的教程和示例的链接。在你深入编码之前,你可能最好先看看它们。