XML 파일을 태그에 상관없이 파싱하고 모든 나뭇잎 (텍스트 요소 만)의 텍스트를 읽어야합니다. 나는 StAX를 사용하고 있지만, 엘리먼트가 텍스트 일 뿐이라는 것을 미리 알 수있는 방법이 없다. 그래서 getElementText는 엘리먼트를 남겨 두지 않는 예외를 던진다. 그래서 난 단지 태그 요소를 필터링 필터를 사용하기로 결정하고, 반복 처리는이 방법으로 문서를 던져 :StAX를 사용하여 모든 텍스트 요소를 읽으십시오
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;
}
}
문제가 있다는 것입니다 I 휴가가 발견되면 다음 예외가 있습니다.
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()는 시작 요소에 의해 호출되어야한다고 생각했습니다. 다른 목표를 달성 할 수있는 방법이 있습니까?
고마워, 그건 내 문제를 해결! – maxqua72