2009-06-20 11 views
17

Ich muss ein XML-Dokument aus einer Java-Objekthierarchie erstellen. Sowohl die Java-Klassen als auch das XML-Format sind festgelegt. Daher kann ich keinen XML-Serializer wie XStream verwenden: Er basiert das XML-Format auf den Java-Klassen. Ebenso funktioniert eine Java-XML-Bindungstechnologie wie JAXB nicht, da sie Java-Klassen aus dem XML-Schema erstellt [ed: aber siehe unten]. Ich brauche einen manuellen Ansatz.Wie erstellt man ein XML-Dokument in Java präzise?

Die Low-Tech-StringBuilder-Route führt zu fragilen und fehlerhaften Code (zumindest für mich!).

Eine API wie JAXP oder JDOM führt zu viel robuster Code, aber diese sind ziemlich ausführlich.

Groovy hat ein elegantes 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') 
    } 
} 

Andere Sprachen (. ZB Ruby) haben noch bessere, obwohl ich mit reinem Java bleiben wollen. Es scheint einige neue XML-Builder für Java zu geben, wie practicalxml und James Murtys xmlbuilder.

Was sind die eleganteren Ansätze zum Erstellen von XML-Dokumenten in Java?

Zusammenfassung:

Jon Doe vorgeschlagen dom4j und jdom.

CurtainDog wurde trotzdem mit JAXB empfohlen, und jherico hat mich darauf hingewiesen, dass dies ein interessanter Vorschlag war: Sie könnten dann Dozer verwenden, um zwischen meinen aktuellen JavaBeans und den JAXB JavaBeans zu mappen.

taggie empfiehlt JIBX und stimmte mit CurtainDog und jherico überein, dass verbindliche Technologien tatsächlich praktisch sind.

StaxMan empfiehlt StaxMate.

Von den Sachen, die ich mir angesehen habe, scheinen practicalxml und James Murtys xmlbuilder die kompaktesten Erbauer zu sein, obwohl sie ziemlich neu sind. Die Bindungstechnologien wie JAXB scheinen zusätzliche Sicherheit/Automatisierung zu bieten. Von den Mainstream-Optionen scheint dom4j anständig, aber immer noch irgendwie ausführlich. Es bietet eine „Fluent Interface“ (Mutatoren einen Verweis auf das mutierte Objekt zurück, so dass sie miteinander verkettet werden), die Ich mag:

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; 
} 

Für Prägnanz Sie eine dünne Fassade über diese API wickeln könnte kurz und bündig zu schaffen Synonyme für einige dieser Methoden (zB attr() anstelle von addAttribute()).

Vielen Dank!

P.S .: Stephan Schmidt arbeitete an einem Java MarkupBuilder, scheint es aber nicht veröffentlicht zu haben.

+0

Bitte reparieren dom4j Link zu http://dom4j.sourceforge.net/ :) –

+0

@PawelVeselov - danke, es ist traurig, wie dom4j.org koopted wurde. –

+0

(O/T) @JimFerrans Ich glaube nicht, dass es kooptiert wurde, sie erwähnen die dom4j-Software einfach nicht mehr. Das Seitenstyling zwischen ihnen und der dom4j-Bibliotheksseite ist zu ähnlich für die Leute, die nicht das gleiche Dach haben :) –

Antwort

8

dom4j oder jdom sind wahrscheinlich die elegantesten, Sie können Code schreiben, wie es Ihnen gefällt. Dom4j hat Builder, wenn ich mich erinnere, und ja der Code ist ausführlicher.

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

Danke, ich hatte dom4j nicht in Betracht gezogen. –

1

Warum verwenden Sie nicht nur JAXB sowieso .. dann wird das Problem zu einem sehr einfachen Objekt Objekt Mapping und Sie vermeiden Xml insgesamt.

+0

Ich muss ein Objekt in XML-Mapping schreiben, wo der XML-Code ein fester Standard ist (CableLabs ADI 1.1) und die Java-Klassen sind ebenfalls voreingestellt. –

+0

Verwenden Sie JAXB, um Java-Klassen dem Schema zuzuordnen, und verwenden Sie dann Dozer, um aus den JAXB-Klassen den vordefinierten Java-Klassen zuzuordnen. – Jherico

+0

@Jherico: Danke, hab Dozer noch nicht gesehen. Sie könnten also das gewünschte Schema verwenden und JAXB verwenden, um daraus eine entsprechende Menge von JavaBean-Klassen zu erstellen, und dann eine Dozer-Zuordnung von den vorhandenen JavaBeans zu den JAXB JavaBeans einrichten. Klingt nach mehr Code, aber auch mehr Automatisierung. Ich sehe, was CurtainDog jetzt bedeutet. –

0

Sie können möglicherweise in Betracht ziehen JIBX, können Sie möglicherweise eine mapping von Ihrem Domänenmodell Klassen zu Ihrem Ziel-XML-Schema definieren.

Alternativ, wenn das nicht möglich ist, obwohl ich weiß, dass Sie mit verbindlichen Technologien diskontiert haben, würde ich Sie ermutigen, diese Entscheidung zu überprüfen, Kopieren von Ihrem Domänenmodell in ein generiertes Modell wird wahrscheinlich sauberer machen, wartungsfreundlicher und weniger fehleranfälliger als das, was Sie vorschlagen (was auch JIBX kann).

Ich sollte wahrscheinlich hinzufügen, nach meiner Erfahrung Fragen zu JIBX hier ist fruchtlos, aber ihre Mailing-Liste ist sehr hilfreich.

1

Obwohl nicht ganz so prägnant wie Builder in Skriptsprachen, macht StaxMate die Dinge ziemlich einfach; in der Regel so einfach wie Baummodelle strukturell, unterstützt aber zusätzlich typisierte Addition (implizite Konvertierungen). Und dies alles direkt in einen Stream, was bedeutet, dass der Speicherverbrauch sehr gering ist (und hohe Geschwindigkeit, wenn das wichtig ist).

Für was es wert ist, unterstützt es auch fließenden Stil (ab 2.0.x), da es oft Sinn macht. Der Hauptvorteil gegenüber vollständigen Datenbindungs- (und Baummodell-) Lösungen ist wahrscheinlich eine geringe Speicherauslastung; es wird sehr wenig Zustand beibehalten, alle Ausgänge werden so schnell wie möglich zum Ziel geführt.

2

Werfen Sie einen Blick auf XOM. Es ist schnell, einfach, korrekt und nicht ausführlich.