Generazione di XML utilizzando SAX e Java

Qualcuno sa di un buon tutorial (o di un buon esempio) per scrivere XML usando il framework SAX (o qualcosa di simile) e Java? La ricerca ha prodotto molto poco in termini di risultati utili. Sto cercando di esportare da un’app per Android e sto cercando di evitare il maggior carico di memoria ansible.

C’è una tecnica molto utile per generare XML direttamente dai POJO attraverso il framework SAX (non un parser SAX, ma il framework SAX). Questa tecnica potrebbe essere utilizzata per generare un documento XML .

Generazione di XML da una struttura di dati arbitraria
http://download.oracle.com/javaee/1.4/tutorial/doc/JAXPXSLT5.html

In sostanza, si aggiungono metodi al POJO o si scrivono classi di utilità per i POJO che li trasformano in emittenti di eventi SAX (l’emissione di eventi come un parser SAX avviene normalmente durante l’analisi di un documento XML). Ora il vostro “generatore di eventi SAX” appare come il lato di output di un parser SAX e può essere fornito a qualsiasi gestore di contenuto che un parser SAX prenderebbe, come uno che stampa pretyy XML. Ma potrebbe anche essere inviato a un parser DOM per generare un albero DOM o un feed a un motore XSLT per generare HTML o eseguire una traduzione XSL vera senza dover prima generare un documento XML intermedio dai POJO.

Ad esempio, una class Person potrebbe avere un metodo emitXML() che include queste righe:

 handler.startElement(nsu, PERSON_TAG, PERSON_TAG, NO_ATTRIBUTES); handler.startElement(nsu, FIRSTNAME_TAG, FIRSTNAME_TAG, atts); handler.characters(this.firstName.toCharArray(), 0, this.firstName.length()); handler.endElement(nsu, FIRSTNAME_TAG, FIRSTNAME_TAG); ... emit more instance variables ... emit child object like: homeAddress.emitXML(handler, ...); handler.endElement(nsu, PERSON_TAG, PERSON_TAG); 

Aggiornare:

Un paio di altri riferimenti:


Un paio di risposte ai commenti:

Questo è vero, ma l’interfaccia XMLStreamWriter descritta sopra è molto più user-friendly. – Michael Kay, 3 ore fa

Sì, ma credo di non essere stato chiaro. Potrei facilmente attraversare la gerarchia e utilizzare XMLStreamWriter per generare direttamente un documento XML in un stream. Tuttavia, gli articoli mostrano una potente tecnica per attraversare la gerarchia e generare eventi SAX, invece di emettere direttamente un documento XML. Ora posso inserire gestori di contenuti diversi che fanno cose diverse o generano versioni diverse dell’XML. Potremmo anche alimentare la nostra gerarchia di oggetti con qualsiasi strumento che abbia accettato un parser SAX, come un motore XSLT. In realtà sta solo sfruttando il modello di visitatore stabilito dal framework SAX: separiamo la gerarchia dall’output dell’XML. Le parti che XMLStreamWriter l’XML, i gestori di contenuto, dovrebbero certamente usare un XMLStreamWriter se il loro scopo è scrivere un stream XML.

Ad esempio, sul nostro programma, abbiamo inviato messaggi XML su socket di rete tra componenti distribuiti e abbiamo anche utilizzato XSLT per generare le nostre pagine HTML. Precedentemente, abbiamo attraversato la nostra gerarchia per generare un documento XML (una stringa) e poi abbiamo scritto quel documento XML su un socket di rete o abbiamo alimentato quel documento al motore XSLT (che essenzialmente lo ha solo analizzato di nuovo). Dopo aver utilizzato questa tecnica, è ansible alimentare essenzialmente la gerarchia degli oggetti (utilizzando questo adattatore SAX) direttamente sul motore XSLT senza la stringa XML intermedia. Era anche comodo poter usare un gestore di contenuti per generare una rappresentazione XML compatta per il stream di rete e usarne uno diverso per generare un documento XML piuttosto stampato da scrivere in un file di registro.

Inoltre, l’uso dell’API parser SAX per scrivere XML è un uso improprio dell’API, IMHO. – Puce 49 minuti fa

Forse, ma penso che dipenda dai tuoi bisogni. Se il requisito dell’OP è solo quello di scrivere un documento XML specifico, allora questo è decisamente eccessivo. Tuttavia, ho pensato che valesse la pena di menzionare se l’OP utilizza l’XML in altri modi sul suo progetto che non ha menzionato. Non c’è nulla di male nel lanciare un’idea alternativa.

Chiamarlo in modo improprio può essere un po ‘forte, ma sono d’accordo che hai diritto alla tua opinione. È documentato in un tutorial Oracle, quindi non è considerato un abuso da parte degli ingegneri Sun / Oracle. Abbiamo avuto molto successo nel nostro progetto per aiutarci a soddisfare i nostri requisiti senza aspetti negativi significativi, quindi terrò questo approccio nella mia casella degli strumenti per quando sarà utile in futuro.

L’analisi SAX serve per leggere i documenti, non per scriverli.

È ansible scrivere XML con XMLStreamWriter:

 OutputStream outputStream = new FileOutputStream(new File("doc.xml")); XMLStreamWriter out = XMLOutputFactory.newInstance().createXMLStreamWriter( new OutputStreamWriter(outputStream, "utf-8")); out.writeStartDocument(); out.writeStartElement("doc"); out.writeStartElement("title"); out.writeCharacters("Document Title"); out.writeEndElement(); out.writeEndElement(); out.writeEndDocument(); out.close(); 

Qui sotto risponde “un buon tutorial per scrivere XML usando il parser SAX e la parte di domanda Java”

Non sono sicuro che tu abbia attraversato questo. Ma mi piace molto l’indice Really Big di Java di tutto .

Passare attraverso questo: http://download.oracle.com/javase/tutorial/jaxp/index.html

E alla fine, questo: http://download.oracle.com/javase/tutorial/jaxp/sax/index.html

Si prega di fare riferimento al mio post sul blog personale: XML Generation In Java – in particolare, il metodo SAX . Fa riferimento ad alcuni altri articoli relativi a questo, fornisce un esempio concreto e confronta SAX con le altre API popolari per la generazione di XML da Java.

(Ho capito che questa è una domanda più vecchia, ma ho ritenuto necessario aggiungerla a chiunque altro possa avere la stessa domanda).

Considerare anche JAXB per scrivere / leggere XML.

Puoi anche bridge to trax con questo:

 public abstract class PipedSAXSource extends SAXSource { protected PipedSAXSource() { setXMLReader(new CallWriteDuringSax()); } protected abstract void writeTo(ContentHandler sink) throws IOException, SAXException; private class CallWriteDuringSax extends XMLFilterImpl { @Override public void parse(InputSource ignored) throws IOException, SAXException { writeTo(getContentHandler()); } @Override public void setFeature(String name, boolean value) {} } } 

Utilizzare in questo modo:

  public static void main(String[] args) throws Exception { Source in = new PipedSAXSource() { @Override protected void writeTo(ContentHandler sink) throws SAXException { sink.startDocument(); sink.startElement("", "root", "root", new AttributesImpl()); sink.endElement("", "root", "root"); sink.endDocument(); } }; Transformsr identity = TransformsrFactory.newInstance().newTransformsr(); identity.transform(in, new StreamResult(System.out)); }