タグに関係なく、xmlファイルを解析し、そのすべての葉のテキストを読み取る必要があります(テキスト要素のみ)。StAXを使用していますが、要素がテキストのみであることを事前に知る方法がないようです(したがって、getElementTextは要素を残さないための例外をスローします)。そこで、フィルターを使用して、タグ要素のみをフィルター処理し、次のようにドキュメントを繰り返しスローすることにしました。
InputStream in = null;
try {
in = new FileInputStream("file.xml");
DatiEstratti de = DatiEstratti.getInstance();
// Processamento ad eventi
XMLInputFactory factory = (XMLInputFactory) XMLInputFactory.newInstance();
XMLEventReader eventReader = factory.createXMLEventReader(in);
// usa il filtro per filtrare solo i tag element
eventReader = factory.createFilteredReader(eventReader, new ElementOnlyFilter());
while (eventReader.hasNext()) {
XMLEvent event = eventReader.nextEvent();
if (event.getEventType() == XMLStreamConstants.START_ELEMENT) {
StartElement startElement = event.asStartElement();
XMLEvent peekEvent = eventReader.peek();
if(peekEvent.isEndElement()){
// questa è la prima volta che viene fatto un pop
// quindi è una foglia.
// recupera il dato.
String value = eventReader.getElementText();
logger.info("dato : " + value);
}
String nome = startElement.getName().getLocalPart();
String prefix = startElement.getName().getPrefix();
if (prefix != null) {
nome = prefix + ":" + nome;
}
de.push(nome);
logger.info("push : " + de.stampaPercorso());
} else if ((event.getEventType() == XMLStreamConstants.END_ELEMENT)) {
de.pop();
logger.info("pop : " + de.stampaPercorso());
if (0 > de.nLivelliPercorso()) {
break;
}
}
//handle more event types here...
}
...ここで、フィルターは次のとおりです。
public class ElementOnlyFilter implements EventFilter, StreamFilter {
/* implementation of EventFilter interface */
@Override
public boolean accept(XMLEvent event) {
return acceptInternal(event.getEventType( ));
}
/* implementation of StreamFilter interface */
@Override
public boolean accept(XMLStreamReader reader) {
return acceptInternal(reader.getEventType( ));
}
/* internal utility method */
private boolean acceptInternal(int eventType) {
return eventType == XMLStreamConstants.START_ELEMENT
|| eventType == XMLStreamConstants.END_ELEMENT;
}
}
問題は、休暇が見つかったときに次の例外が発生したことです。
javax.xml.stream.XMLStreamException: ParseError at [row,col]:[3,42]
Message: parser must be on START_ELEMENT to read next text
at com.sun.xml.internal.stream.XMLEventReaderImpl.getElementText(XMLEventReaderImpl.java:114)
at javax.xml.stream.util.EventReaderDelegate.getElementText(EventReaderDelegate.java:88)
at xmlparser.XmlParser.main(XmlParser.java:63)
どうしよう。このコードに誤りはありますか?peek()はリーダーを変更しないので、getElementText()はstart要素によって呼び出される必要があると思いました。私の目標を達成する別の方法はありますか?