ソケットから読み取り、完全な XML ドキュメントを返す XMLReader を実装しようとしています。
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Stack;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
public class MyXmlReader {
private final XMLInputFactory infactory = XMLInputFactory.newInstance();
private final InputStream inStream;
public MyXmlReader(final InputStream inStream){
this.inStream= inStream;
}
private String readUntilEndOfXml() throws XMLStreamException{
final XMLEventReader eventReader= infactory.createXMLEventReader(inStream);
final StringBuilder sb= new StringBuilder();
final Stack<String> openTags= new Stack<String>();
boolean endOfXml= false;
while (eventReader.hasNext() && !endOfXml){
final XMLEvent nextEvent= eventReader.nextEvent();
sb.append(nextEvent.toString());
if (nextEvent.isStartElement()){
openTags.add(nextEvent.toString());
}else if (nextEvent.isEndElement()){
openTags.pop();
if (openTags.isEmpty()){
endOfXml= true;
}
}
}
eventReader.close();
return sb.toString();
}
public static void main(String[] args) throws Exception {
final File f= new File("/tmp/double.xml");
final MyXmlReader r= new MyXmlReader(new FileInputStream(f));
String xml;
while((xml= r.readUntilEndOfXml()) != null){
System.out.println("Got an XML");
}
}
}
ただし、ファイルの最後に到達した場合 (またはソケットからの読み取り時にソケットが閉じられた場合) は、次の例外が発生します。
javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: Premature end of file.
at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:594)
at com.sun.xml.internal.stream.XMLEventReaderImpl.nextEvent(XMLEventReaderImpl.java:85)
at com.siemens.bfr2.plato.MyXmlReader.readUntilEndOfXml(MyXmlReader.java:40)
at com.siemens.bfr2.plato.MyXmlReader.main(MyXmlReader.java:125)
のチェックでeventReader.hasNext()
十分だと思っていました。実際にはこれ以上データがないのに、なぜeventReader.hasNext()
まだ を返すのですか?true