Domanda

Devo creare un documento XML da una gerarchia di oggetti Java. Sia le classi Java che il formato XML sono fissi. Quindi non posso usare un serializzatore XML come XStream : basa il formato XML sulle classi Java. Allo stesso modo, una tecnologia di associazione XML Java come JAXB non funzionerà, poiché crea classi Java dallo schema XML [ ed: ma vedi sotto]. Ho bisogno di un approccio manuale.

Il percorso StringBuilder a bassa tecnologia si traduce in un codice fragile e difettoso (almeno per me!).

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

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 (ad es. Ruby ) ne hanno ancora di migliori, anche se voglio rimanere con Java puro. Sembra che ci siano alcuni nuovi compilatori XML per Java, come practicexml e James Murty's xmlbuilder .

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

Riepilogo:

Jon Doe ha suggerito dom4j e jdom .

CurtainDog mi ha consigliato comunque di usare JAXB e jherico mi ha fatto capire che si trattava di un suggerimento pertinente: potevi quindi usare Dozer per mappare tra i miei JavaBean attuali e i JavaBeans JAXB.

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

StaxMan raccomanda StaxMate .

Delle cose che ho visto, practicexml e xmlbuilder di James Murty sembrano essere i costruttori più concisi, sebbene siano piuttosto nuovi. Le tecnologie vincolanti come JAXB sembrano offrire ulteriore sicurezza / automazione. Tra le scelte principali, dom4j sembra decente, sebbene sia ancora piuttosto prolisso. Offre un'interfaccia "fluente" (i mutatori restituiscono un riferimento all'oggetto mutato in modo che possano essere concatenati insieme), 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 concisione, potresti avvolgere una sottile facciata su questa API per fornire sinonimi concisi per alcuni di questi metodi (ad esempio attr () anziché addAttribute ()).

Grazie a tutti!

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

È stato utile?

Soluzione

dom4j o jdom sono probabilmente i più eleganti, puoi scrivere il codice come preferisci. Dom4j ha dei costruttori, se ricordo, e sì, il codice è più dettagliato.

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

Altri suggerimenti

Dai un'occhiata a XOM . È veloce, semplice, corretto e non dettagliato.

Perché non usi JAXB comunque ... allora il problema diventa un oggetto molto semplice per mappare gli oggetti ed eviti del tutto l'xml.

Anche se non abbastanza conciso come i costruttori nei linguaggi di scripting, StaxMate rende le cose abbastanza semplici; generalmente semplice come i modelli ad albero strutturalmente, ma supporta inoltre l'addizione tipizzata (conversioni implicite). E fa tutto direttamente in un flusso, il che significa un utilizzo della memoria molto basso (e alta velocità se ciò è importante).

Per quello che vale, supporta anche lo stile fluente (dalla versione 2.0.x), poiché spesso ha senso. Il vantaggio principale rispetto alle soluzioni di associazione dati completa (e modello ad albero) è probabilmente il basso utilizzo della memoria; viene mantenuto pochissimo stato, tutto l'output arriva a destinazione il più presto possibile.

Potresti essere in grado di considerare JIBX , potresti essere in grado di definire un mapping dalle classi del tuo modello di dominio allo schema XML di destinazione.

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

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top