Возможно, но это как-то некрасиво и хаки sh. Вы можете использовать StAX и считать открывающий и закрывающий теги элементов. Увеличьте счетчик на открывающем теге и уменьшите на закрывающем теге. Когда вы достигаете 0
, вы знаете, что полностью прочитали элемент root. Используйте метод getLocation()
на XMLStreamReader
, чтобы увидеть, как далеко вы прочитали, особенно метод getCharsetOffset()
. С новой позицией / смещением от вашего исходного источника / потока вы можете построить новый поток с начальной точкой в следующем объявлении XML. В качестве подтверждения концепции см. Следующий код:
String content = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"+
"<foobar>\n"+
" <bla />\n"+
"</foobar>\n"+
"<?xml version=\"1.0\" encoding=\"ASCII\" ?>\n"+
"<first with=\"attributes\">\n"+
" <second>\n"+
" <third />\n"+
" </second>\n"+
"</first>";
XMLInputFactory factory = XMLInputFactory.newFactory();
InputStream stream = new ByteArrayInputStream(content.getBytes());
XMLStreamReader xmlReader = factory.createXMLStreamReader(stream);
int nestingCounter = 0;
int characterOffset = 0;
while(xmlReader.hasNext()) {
int event = xmlReader.next();
characterOffset = xmlReader.getLocation().getCharacterOffset();
if (event == XMLStreamConstants.START_ELEMENT) {
nestingCounter++;
}
if (event == XMLStreamConstants.END_ELEMENT) {
nestingCounter--;
}
// work with the event/data here
System.out.println(event);
if (nestingCounter == 0) {
break;
}
}
System.out.println("Second XML");
// build a new stream
content = content.substring(characterOffset).trim();
xmlReader = factory.createXMLStreamReader(new ByteArrayInputStream(content.getBytes()));
// now, again...
while(xmlReader.hasNext()) {
int event = xmlReader.next();
if (event == XMLStreamConstants.START_ELEMENT) {
nestingCounter++;
}
if (event == XMLStreamConstants.END_ELEMENT) {
nestingCounter--;
}
// work with the event/data here
System.out.println(event);
if (nestingCounter == 0) {
break;
}
}
Это сгенерирует следующий вывод (а не вызовет исключение):
1
4
1
2
4
2
Second XML
1
4
1
4
1
2
4
2
4
2
Очевидно, вы должны использовать правильный l oop и закройте потоки и читателей, это только подтверждение концепции. Кроме того, вы можете столкнуться с проблемами, если у вас есть другие вещи между закрывающим тегом предыдущего элемента root и новым объявлением XML, потому что вы можете иметь этот материал в конце, но не в начале документа XML:
2.1 Правильно оформленные XML Документы
document ::= prolog element Misc*
2.8 Пролог и декларация типа документа
Misc ::= Comment | PI | S