2010-04-16 11 views
6

Aggiornamento Non esiste un parser XML pronto nella comunità Java che possa eseguire l'analisi NIO e XML. Questo è il più vicino che ho trovato, ed è incompleta: http://wiki.fasterxml.com/AaltoHomeXMLStreamReader e un flusso reale

ho il seguente codice:

InputStream input = ...; 
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance(); 

XMLStreamReader streamReader = xmlInputFactory.createXMLStreamReader(input, "UTF-8"); 

domanda è, perché il metodo #createXMLStreamReader() si aspetta di avere un intero documento XML in ingresso lo streaming? Perché si chiama "lettore di stream", se non sembra che elabori una porzione di dati XML? Per esempio, se mi nutro:

<root> 
    <child> 

, mi direbbe che mi mancano i tag di chiusura. Anche prima di iniziare a ripetere il lettore di stream stesso. Ho il sospetto che non so come usare correttamente un XMLStreamReader. Dovrei essere in grado di fornirgli dati a pezzi, giusto? Ne ho bisogno perché sto elaborando un flusso XML proveniente dal socket di rete e non voglio caricare l'intero testo sorgente in memoria.

Grazie per l'aiuto, Yuri.

risposta

1

Se è assolutamente necessario NIO con contenuto "push", ci sono sviluppatori interessati a completare API per Aalto. Parser stesso è completo di implementazione Stax e "input push" alternativo (input di alimentazione invece di utilizzare InputStream). Quindi potresti voler controllare le mailing list se sei interessato. Non tutti leggono le domande StackOverflow. :-)

1

Il flusso deve contenere il contenuto per un intero documento XML, ma non tutti in memoria contemporaneamente (questo è ciò che fanno i flussi). Potresti essere in grado di mantenere il flusso e il lettore aperti per continuare a fornire contenuti; tuttavia, dovrebbe essere parte di un documento XML ben formato.

Suggerimento: potresti leggere un po 'di più su come funzionano i socket e gli stream prima di andare molto più lontano.

Spero che questo aiuti.

+1

Sì, potenzialmente lo stream deve contenere un intero documento. Ma perché XMLStreamReader dovrebbe provare a convalidare tutto in anticipo? È un flusso. Perché non può semplicemente andare insieme ai dati e analizzare tutto ciò che è disponibile? E * se * incontra un errore, vorrei affrontarlo da solo. Correggimi se ho torto - stai dicendo che se sto leggendo un documento XML da 1 gigabyte su una rete, dovrei scaricare tutto e solo allora XMLStreamReader sarebbe in grado di scorrere su di esso? –

+0

Penso che non verrebbe convalidato finché l'intero stream non sarà stato elaborato (e chiuso). Non dovresti scaricare tutto, ecco a cosa servono i flussi. Stai scrivendo sul flusso e poi lo chiudi e stai cercando di scrivere di più? – cjstehno

+0

Yuri, no, i parser di Stax NON lo leggeranno prima per intero; puoi sicuramente iniziare a leggere subito, e il parser bloccherà solo se non ha ancora dati da analizzare. Non so quale sia il problema, ma la tua comprensione è corretta. – StaxMan

-2

Guarda questo link per capire di più su come funzionano i parser di streaming e come ti fa risparmiare la memoria di memoria. Per XML in entrata, è necessario innanzitutto serializzare il codice XML in arrivo e creare un XML ben formato, quindi assegnarlo al parser di streaming.

http://www.devx.com/xml/Article/34037/1954

0

Quale versione di Java stai usando? Con JDK 1.6.0_19, ottengo il comportamento che ti aspetti. L'iterazione di tuo esempio frammento XML mi dà tre eventi:

  • START_ELEMENT (radice)
  • caratteri (spazi bianchi tra e)
  • START_ELEMENT (bambino)

La quarta invocazione di next() genera un XMLStreamException: ParseError in [row, col]: [2,12] Messaggio: le strutture del documento XML devono iniziare e terminare all'interno della stessa entità.

+0

Questo è lo stesso di Woodstox. La domanda è sbagliata nell'implicare il contrario. – StaxMan

2

È possibile ottenere ciò che si desidera - un analisi parziale, ma non è necessario chiudere il flusso quando si raggiunge la fine dei dati attualmente disponibili. Mantieni aperto il flusso e il parser semplicemente bloccherà quando arriverà alla fine del flusso. Quando hai più dati, aggiungili allo stream e il parser continuerà.

Questa disposizione richiede due thread: un thread che esegue il parser e altri dati di recupero. Per collegare i due thread, si utilizza una pipe: una coppia PipeInputStream e PipeOutputStream che spinge i dati dal thread del lettore nel flusso di input utilizzato dal parser. (Il parser legge i dati da PipeInputStream.)

+0

Avrei dovuto chiarire che il blocco non è un'opzione nel mio caso. Quando non ci sono più dati disponibili per la lettura (al momento dell'invocazione) il parser dovrebbe trattarlo come una situazione normale e fornirmi qualsiasi cosa abbia analizzato dai dati parziali. –

Problemi correlati