Scenario: Ricevo un enorme file xml tramite una rete estremamente lenta, quindi desidero iniziare l'elaborazione in eccesso il prima possibile. Per questo motivo ho deciso di utilizzare SAXParser.Perché SAXParser legge tanto prima di lanciare eventi?
Mi aspettavo che dopo che un tag è finito otterrò un evento.
Il seguente test mostra cosa intendo:
@Test
public void sax_parser_read_much_things_before_returning_events() throws Exception{
String xml = "<a>"
+ " <b>..</b>"
+ " <c>..</c>"
// much more ...
+ "</a>";
// wrapper to show what is read
InputStream is = new InputStream() {
InputStream is = new ByteArrayInputStream(xml.getBytes());
@Override
public int read() throws IOException {
int val = is.read();
System.out.print((char) val);
return val;
}
};
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(is, new DefaultHandler(){
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.print("\nHandler start: " + qName);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.print("\nHandler end: " + qName);
}
});
}
ho avvolto il flusso di ingresso per vedere ciò che viene letto e quando si verificano gli eventi.
Quello che mi aspettavo era qualcosa di simile:
<a> <- output from read()
Handler start: a
<b> <- output from read()
Handler start: b
</b> <- output from read()
Handler end: b
...
Purtroppo il risultato è stato seguito:
<a> <b>..</b> <c>..</c></a> <- output from read()
Handler start: a
Handler start: b
Handler end: b
Handler start: c
Handler end: c
Handler end: a
Dove è il mio errore e come posso ottenere il risultato atteso?
Edit:
- La prima cosa è che lui sta cercando di rilevare la versione doc, che fa sì che per eseguire la scansione di tutto. Con la versione doc interviene (ma non dove mi aspetto)
- Non va bene che "vuole" leggere ad esempio 1000 byte e blocchi per così tanto tempo perché è possibile che quel flusso non contenga così tanto in questo punto del tempo.
- Ho trovato le dimensioni del buffer in XMLEntityManager:
- pubblico static finale int DEFAULT_BUFFER_SIZE = 8192;
- public static final int DEFAULT_XMLDECL_BUFFER_SIZE = 64;
- public static final int DEFAULT_INTERNAL_BUFFER_SIZE = 1024;
Penso che dovresti provare un bug test file - sospetto che una lettura bufferizzata stia effettivamente leggendo l'intero file prima che inizi l'elaborazione perché bufferizzerebbe il file in (diciamo) blocchi di 1k o qualsiasi altra cosa - se usi un file di grandi dimensioni potresti ottenere qualcosa di più come ti aspetti. – Elemental