Да, это можно сделать.Я предполагаю, что вы используете реализацию org.xml.sax (но базовый метод должен работать с любым парсером SAX-типа).
При использовании SAX у вас есть XMLParser
, который выполняет фактический анализи вы передаете ему объект, реализующий (например) интерфейс ContentHandler
.
Если вы хотите обрабатывать элементы отдельно от меню, вы используете two 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
находится под контролем.
Первое, с чем он сталкивается, это тег <menu>
в строке 1. Это указывает на начало пункта меню, поэтомумы переключаемся на MenuContentHandler
(это помечено как «Точка 3» выше), чтобы мы могли прочитать содержимое элемента меню.
В этом случае первое, что в элементе - это элемент item.(строка 2), так же, как мы меняем тo ItemContentHandler
, чтобы он мог обрабатывать содержимое элемента item (на этот раз в точке 1).
Строка 3 повторяет строку 1, поэтому мы снова переключаемся на MenuContentHandler
впункт 3, чтобы проверить содержимое элемента меню.
Следующим элементом является тег <content/>
в строке 4, который обрабатывается MenuContentHandler
(который, как я упоминал в предыдущем абзаце, в настоящее время)
В строке 5 меню закрывается тегом </menu>
.Теперь, поскольку все элементы меню содержатся в элементах item, мы знаем, что теперь мы должны быть в элементе item, содержащем меню.Поэтому мы переключаемся на ItemContentHandler
.Это точка 2.
Строка 6 запускает новый пункт меню, и поэтому обрабатывается так же, как строки 1 и 3. И так для строк с 7 по 11.
Строка 12 заканчиваетсяэлемент items и с помощью эквивалентной логики, как для строк 5, 8 и 11, мы знаем, что теперь мы должны быть в элементе меню, который содержит элемент item.Таким образом, мы изменяем на MenuContentHandler
(точка 4).
Строка 12 является концом пункта меню, и поэтому обрабатывается так же, как строки 5, 8 и 11.
Надеюсь, это объясняет это немного лучше!