2009-06-20 5 views
17

Ho bisogno di creare un documento XML da una gerarchia di oggetti Java. Sia le classi Java che il formato XML sono corretti. Quindi non posso usare un serializzatore XML come XStream: basa il formato XML sulle classi Java. Allo stesso modo, una tecnologia di collegamento XML Java come JAXB non funzionerà, dal momento che crea classi Java dallo schema XML [ed: ma vedi sotto]. Ho bisogno di un approccio manuale.Come creare in modo conciso un documento XML in Java?

Il percorso StringBuilder a bassa tecnologia genera codice fragile e buggato (almeno per me!).

Un'API come JAXP o JDOM porta a codice molto più robusto, ma questi sono piuttosto prolissi.

Groovy ha un elegante MarkupBuilder:

def writer = new StringWriter() 
def xml = new MarkupBuilder(writer) 
xml.records() { 
    car(name:'HSV Maloo', make:'Holden', year:2006) { 
    country('Australia') 
    record(type:'speed', 'Production Pickup Truck with speed of 271kph') 
    } 
    car(name:'P50', make:'Peel', year:1962) { 
    country('Isle of Man') 
    record(type:'size', 'Smallest Street-Legal Car at 99cm wide and 59 kg') 
    } 
} 

Altre lingue (es. Ruby) hanno quelli ancora migliori, se io voglio stare con Java puro. Sembrano esserci alcuni nuovi builder XML per Java, come ad esempio practicalxml e James Murty's xmlbuilder.

Quali sono gli approcci più eleganti per la creazione di documenti XML in Java?

Sommario:

Jon Doe suggerito dom4j e jdom.

CurtainDog ha raccomandato comunque l'uso di JAXB e Jherico mi ha suggerito che si trattava di un suggerimento pertinente: era quindi possibile utilizzare Dozer per eseguire il mapping tra i miei attuali JavaBeans e JAXB JavaBeans.

thaggie consiglia JIBX e concordato con CurtainDog e jherico che le tecnologie vincolanti sono effettivamente pratiche.

StaxMan raccomanda StaxMate.

Delle cose che ho visto, il pratico xml e l'xml builder di James Murty sembrano essere i costruttori più concisi, anche se sono piuttosto nuovi. Le tecnologie di binding come JAXB sembrano offrire sicurezza/automazione extra. Delle scelte tradizionali, dom4j sembra decente, sebbene sia ancora un po 'prolisso. Esso offre una "interfaccia fluida" (mutatori restituiscono un riferimento all'oggetto mutato in modo che possano essere concatenati), che mi piace:

public Document createDocument() { 
    Document document = DocumentHelper.createDocument(); 
    Element root = document.addElement("root"); 
    Element author2 = root.addElement("author") 
     .addAttribute("name", "Toby") 
     .addAttribute("location", "Germany") 
     .addText("Tobias Rademacher"); 
    Element author1 = root.addElement("author") 
     .addAttribute("name", "James") 
     .addAttribute("location", "UK") 
     .addText("James Strachan"); 
    return document; 
} 

Per brevità, si potrebbe avvolgere una facciata sottile sopra questa API per fornire laconico sinonimi per alcuni di questi metodi (ad es. attr() invece di addAttribute()).

Grazie a tutti!

P.S .: Stephan Schmidt ha lavorato su un Java MarkupBuilder, anche se sembra non averlo pubblicato.

+0

Si prega di correggere il collegamento dom4j a http://dom4j.sourceforge.net/ :) –

+0

@PawelVeselov - grazie, è triste come dom4j.org è stato cooptato. –

+0

(O/T) @JimFerrans Non penso che sia stato cooptato, semplicemente non citano più il software dom4j. Lo stile della pagina tra loro e la pagina della libreria dom4j è troppo simile per quei ragazzi che non hanno lo stesso tetto :) –

risposta

8

dom4j o jdom sono probabilmente i più eleganti, è possibile scrivere codice come ti piace. Dom4j ha costruttori se ricordo, e sì il codice è più prolisso.

Element.addElement("x").setAttribute("x", "y").xxxxx; 
+0

Grazie, non avevo considerato dom4j. –

1

Perché non basta usare JAXB comunque .. allora il problema diventa un oggetto molto semplice da obiettare mappatura e di evitare xml del tutto.

+0

Ho bisogno di scrivere un oggetto per la mappatura XML dove l'XML è uno standard fisso (ADL 1.1 di CableLabs) e anche le classi Java sono preordinate. –

+0

Utilizzare JAXB per associare le classi java allo schema e quindi utilizzare Dozer per eseguire il mapping dalle classi JAXB alle classi java pre-ordinate. – Jherico

+0

@Jherico: Grazie, non ho ancora visto Dozer. Quindi è possibile prendere lo schema desiderato e utilizzare JAXB per creare un corrispondente set di classi JavaBean, quindi impostare una mappatura Dozer dai JavaBeans esistenti ai JBob JavaBeans. Sembra più codice ma anche più automazione. Vedo cosa significa CurtainDog ora. –

0

Potrebbe essere possibile considerare JIBX, è possibile definire un mapping dalle classi del modello di dominio allo schema XML di destinazione.

In alternativa, se ciò non è possibile, anche se so che dichiari di aver scontato l'utilizzo di tecnologie di binding, ti incoraggio a rivedere tale decisione, la copia dal modello di dominio in un modello generato molto probabilmente renderà più pulito, più manutenibile e meno codice soggetto a errori rispetto a quello che stai proponendo, (che JIBX può anche fare).

Probabilmente dovrei aggiungere, nella mia esperienza fare domande su JIBX qui è inutile ma la loro mailing list è molto utile.

1

Sebbene non abbastanza conciso come i builder nei linguaggi di scripting, StaxMate semplifica le cose; generalmente semplice come i modelli ad albero strutturalmente, ma supporta anche l'aggiunta tipizzata (conversioni implicite). E tutto questo direttamente in un flusso, che significa utilizzo della memoria molto basso (e alta velocità se ciò è importante).

Per quello che vale, supporta anche lo stile fluente (a partire da 2.0.x), poiché spesso ha senso. Il vantaggio principale rispetto alle soluzioni complete di data binding (e modello ad albero) è probabilmente l'utilizzo di memoria insufficiente; lo stato molto piccolo è tenuto in giro, tutto l'output va a destinazione il più presto possibile.

2

Dai uno sguardo allo XOM. È veloce, semplice, corretto e non è prolisso.