Wie kann man in Java auf XML-Dokumente zugreifen?

Unter Java existieren mehrere Möglichkeiten, um auf XML-Dokumente zuzugreifen. Alle besitzen spezifische Vor- und Nachteile. Die zwei möglicherweise gängigsten werden hier kurz vorgestellt.

Als Beispiel verwenden wir eine einfache XML-Datei:

<?xml version="1.0" encoding="UTF-8"?>
<Adresse>
    <Nachname>Meier</Nachname>
    <Vorname>Willi</Vorname>
    <Strasse>
        <Name>Schlossallee</Name>
        <Nr>34</Nr>
    </Strasse>
    <Ort name="Hamburg" plz="20001"/>
</Adresse>

Zunächst muss mit Hilfe der Klasse SAXBuilder ein JDOM-Dokument erzeugt werden. Durch ein XMLOutputter-Objekt kann dies schließlich als Byte-Strom in vielfältig formatierter Weise ausgegeben werden. Hierzu dient die Klasse Format. Ein Konstruktor ohne Parameterangabe entspricht der Übergabe von Format.getRawFormat().
Die Methode output() sorgt für die Ausgabe und erhält als Parameter das Dokument und einen OutputStream oder Writer.
Mit Hilfe entsprechender Methoden lässt sich jetzt problemlos auf das Wurzelelement, Kindelemente, Attribute und Werte zugreifen.

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

class JDOMLesen {

    public static void main(String[] args) {

        Document doc = null;

        File f = new File("xml_file.xml");

        try {
            // Das Dokument erstellen
            SAXBuilder builder = new SAXBuilder();
            doc = builder.build(f);
            XMLOutputter fmt = new XMLOutputter();

            // komplettes Dokument ausgeben
            fmt.output(doc, System.out);

            // Wurzelelement ausgeben
            Element element = doc.getRootElement();
            System.out.println("\nWurzelelement: " + element);

            // Wurzelelementnamen ausgeben
            System.out.println("Wurzelelementname: " + element.getName());

            // Eine Liste aller direkten Kindelemente eines Elementes erstellen
            List alleKinder = (List) element.getChildren();
            System.out.println("Erstes Kindelement: "
                    + ((Element) alleKinder.get(0)).getName());

            // Eine Liste aller direkten Kindelemente eines benannten
            // Elementes erstellen
            List benannteKinder = element.getChildren("Strasse");

            // Das erste Kindelement ausgeben
            System.out.println("benanntes Kindelement: "
                    + ((Element) benannteKinder.get(0)).getName());

            // Wert eines bestimmten Elementes ausgeben
            Element kind = element.getChild("Nachname");
            System.out.println("Nachname: " + kind.getValue());

            // Attribut ausgeben
            Element kind2 = element.getChild("Ort");
            System.out.println("Ortsname: " + kind2.getAttributeValue("name"));
        } catch (JDOMException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Das "Simple API for XML Parsing (SAX)" basiert auf einem Ereignismodell und liest eine XML-Datei wie einen Datenstrom.
Die Basis bildet ein Handler-Objekt, das durch Erweitern der Klasse DefaultHandler erzeugt wird. Zur Ausgabe werden üblicherweise fünf Methoden überschrieben, die per default nichts unternehmen. Sie dienen der Manipulation, des im jeweiligen Methodennamen angesprochenen Dateibereiches.
Zur Demonstration der Arbeitsweise werden an zwei Stellen "xxx", bzw. "+++" eingefügt.

import java.io.*;

import javax.xml.parsers.*;

import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

public class SAXLesen extends DefaultHandler {
    static final String neueZeile = System.getProperty("line.separator");

    static private Writer out = null;

    private StringBuffer textBuffer = null;

    public static void main(String[] argv) {

        // SAX-EventHandler erstellen
        DefaultHandler handler = new SAXLesen();

        // Inhalt mit dem Default-Parser parsen
        SAXParser saxParser;

        try {
            saxParser = SAXParserFactory.newInstance().newSAXParser();
            saxParser.parse(new File("xml_file.xml"), handler);
        } catch (ParserConfigurationException pe) {
            pe.printStackTrace();
        } catch (SAXException se) {
            se.printStackTrace();
        } catch (IOException ie) {
            ie.printStackTrace();
        }
    }

    // SAX DefaultHandler Methoden

    public void startDocument() throws SAXException {
        ausgabe("auf geht's!" + neueZeile);
    }

    public void endDocument() throws SAXException {
        ausgabe("finito!" + neueZeile);
    }

    // Starttag auslesen
    public void startElement(String namespaceURI, String localName,
            String qName, Attributes attrs) throws SAXException {
        textPuffer();
        String eName = ("".equals(localName)) ? qName : localName;
        ausgabe("<" + eName);

        // Erfassen der Attribute in den Starttags
        if (attrs != null) {
            for (int i = 0; i < attrs.getLength(); i++) {
                String aName = attrs.getLocalName(i);
                if ("".equals(aName))
                    aName = attrs.getQName(i);
                ausgabe(" " + aName + "=\"" + attrs.getValue(i) + "\"");
            }
        }
        ausgabe(">");
    }

    // Schlusstags auslesen
    public void endElement(String namespaceURI, String localName, String qName)
            throws SAXException {
        textPuffer();
        String eName = ("".equals(localName)) ? qName : localName;
        ausgabe("</" + eName + ">");
    }

    // Erzeugt einen String aus den Char-Arrays und liest
    // diesen in einen StringBuffer ein
    public void characters(char[] buf, int offset, int len) throws SAXException {
        String s = new String(buf, offset, len);
        if (textBuffer == null)
            textBuffer = new StringBuffer(s);
        else
            textBuffer.append(s);
    }

    /** ************** Hilfsmethoden ******************* */

    // Wandelt den StringBuffer in einen String und
    // &uuml;bergibt ihn zur Ausgabe
    // "xxx" verdeutlicht die Arbeitsweise
    private void textPuffer() throws SAXException {
        if (textBuffer == null)
            return;
        ausgabe("xxx" + textBuffer.toString());
        textBuffer = null;
    }

    // Ausgabe des Strings
    // "+++" verdeutlicht die Arbeitsweise
    private void ausgabe(String s) throws SAXException {
        try {
            if (out == null)
                out = new OutputStreamWriter(System.out, "UTF8");
            out.write(s + "+++");
            out.flush();
        } catch (IOException ex) {
            throw new SAXException("Ein-/Ausgabefehler", ex);
        }
    }
}

1) JDOM muss vor der Benutzung von der Webseite des JDOM-Projektes heruntergeladen und in den Classpath eingebunden werden.
Bei Verwendung von JDOM2 müssen die Import-Aweisungen von "import org.jdom..." auf "import org.jdom2..." angepasst werden.

Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.

letzte Änderung an:
Streams


Javabeginners News-Feed News-Feed abonnieren