Wie kann eine XML-Datei mit Java erstellt werden?

Die wohl einfachste Form eine XML-Datei mit Java zu schreiben, stellt das Framework JDOM1 dar. Das Beispiel demonstriert dies anhand einer einfachen XML-Datei.

Die Datei wird in drei Schritten erstellt, die durch gesonderte Methoden repräsentiert werden. Sie werden der Reihe nach in main() aufgerufen.

Erstellen des Document‑Objektes.

Der Inhalt einer XML-Datei wird durch ein Document‑Objekt repräsentiert, das hier in der Methode createDoc() erzeugt wird. Dem Konstruktor werden im Beispiel der Bezeichner des Rootelementes und der Namensraum übergeben. Die Übergaben lassen sich je nach Anforderung variieren, da die Klasse fünf überladene Konstruktoren definiert.
Die Knoten eines XML-Dokumentes werden bei JDOM als Elemente bezeichnet. Wie alle Elemente wird auch das Rootelement als Element‑Objekt erzeugt. Auch die Element-Klasse definiert fünf überladene Konstruktoren. Sie stellt mannigfaltige Methoden für den Zugriff auf Elemente, wie das Hinzufügen und Ändern von Daten, Attributen und Elementen selbst bereit.
Im vorliegenden Beispiel wird dem Konstruktor der Klasse beim Erzeugen des Objektes neben dem Elementbezeichner noch ein String des Namensraums in Form einer URL übermittelt.
Die Methode setRootElement() setzt das erzeugte Element‑Objekt als Rootelement des Document‑Objektes.

Der Inhalt der XML-Datei

Die Methode writeDoc() erzeugt den Inhalt des XML-Dokumentes. Er besteht unterhalb des Rootelementes aus zwei Knoten e1 und e2, von denen der erste zwei Attribute, name und value, und der zweite zwei gleichnamige Unterknoten mit entsprechenden Werten besitzt.

<?xml version="1.0" encoding="UTF-8"?>
<elements xmlns="https://javabeginners.de/xml">
    <e1 xmlns="" name="e1" value="Wert 1" />
    <e2 xmlns="">
        <name>e2</name>
        <value>Wert 2</value>
    </e2>
</elements>

Der oberste Knoten, das Rootelement, wurde dem Dokument bereits bei dessen Erzeugung hinzugefügt. In dieses werden nun die genannten Elemente als Unterknoten eingefügt. Hierzu wird in der Methode writeDoc() für jeden Knoten ein entsprechendes Objekt erzeugt und hierbei der Bezeichner als Stringparameter übergeben.
Die XML-Parameter der Knoten werden dann über die Methode setAttribute() der Element‑Objekte erzeugt und diesen hinzugefügt. Hierbei werden die Bezeichner und Werte wiederum als Stringparameter beim Methodenaufruf übergeben.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.swing.JOptionPane;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

public class JDOMSchreiben {

    private final static String DATNAM = "xmlTest.xml";

    private final static File FILE = new File(DATNAM);

    private final static String NAMESPACE = "https://javabeginners.de/xml";

    private Document createDoc(String rootElement) {
        Document doc = new Document();
        Element root = new Element(rootElement, NAMESPACE);
        doc.setRootElement(root);
        return doc;
    }

    private void writeDoc(Document doc) {
        Element e1 = new Element("e1");
        e1.setAttribute("name", e1.getName());
        e1.setAttribute("value", "Wert 1");
        doc.getRootElement().addContent(e1);
        Element e2 = new Element("e2");
        Element n2 = new Element("name");
        n2.setText("e2");
        Element v2 = new Element("value");
        v2.setText("Wert 2");
        e2.addContent(n2);
        e2.addContent(v2);
        doc.getRootElement().addContent(e2);
    }

    private void writeXML(Document doc) {
        Format format = Format.getPrettyFormat();
        format.setIndent("    ");
        try (FileOutputStream fos = new FileOutputStream(FILE)) {
            XMLOutputter op = new XMLOutputter(format);
            op.output(doc, fos);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        JDOMSchreiben jds = new JDOMSchreiben();
        Document doc = jds.createDoc("elements");
        jds.writeDoc(doc);
        jds.writeXML(doc);
    }
}

Die Erstellung weiterer Unterknoten erfolgt auf gleiche Weise. Im Gegensatz zum Eintrag der Werte bei Attributen, findet dieser bei Elementen jedoch mit setText() statt.
Die fertig konfigurierten Elemente werden schließlich durch die Methode Element#addContent()dem jeweils übergeordneten Knoten hinzugefügt. Hierbei kann durch Verwenden von Document#getRootElement() direkt auf den Wurzelknoten zugegriffen werden.

Speichern

In writeXML() findet die Ausgabe des Dokumentes in eine Datei durch einen FileOutputStream statt, der mit dem Dateipfad als Argument gebildet wird. Ihm wird das Dokument in Form eines Bytestroms übergeben. Die Methode output eines XMLOutputter-Objektes erhält hierzu das erzeugte Dokument und den FileOutputStream als Parameter.
Der XMLOutputter dient der Formatierung des Dokuments. Ein ihm übergebenes Format-Objekt formatiert über die Methoden getPrettyFormat() und setIndent() die Zeilenumbrüche und Einrückungen des ausgegebenen XML-Dokumentes.

Auf zwei Punkte soll an dieser Stelle hingewiesen werden:

  1. Wird der Stream nicht wie hier mit einem try-with-resources-Block erzeugt, so müssen dessen Ressourcen abschließend üblicherweise mit flush() freigegeben und die Datei mit close() geschlossen werden. Die Aufgabe der Ressourcen-Freigabe wird bei Verwendung eines XMLOutputter durch dessen Methode output übernommen. Sie schließt jedoch nicht die Datei!
  2. Findet die Ausgabe über einen Writer und nicht wie hier über einen Stream statt, so muss darauf geachtet werden, dass der beim Format-Objekt verwendete Zeichensatz auch dem im Header der XML-Datei angegebenen entspricht. Gegebenenfalls kann dies mittels Format#setEncoding() eingestellt werden. Als Standard wird UTF-8 verwendet.

1) JDOM muss vor der Benutzung von der Webseite des JDOM-Projektes heruntergeladen und in den Classpath eingebunden werden.