Lehrer Nussbaumer - JAVA (eine kleine Einführung ;)

Grundlagen

GUI

Eingabe

Ausgabe

Applikationen

Applets

Servlets

Beispiele

  1. Ein- und Ausgabe
  2. Textdateien
  3. Kryptographie
  4. MySQL
  5. DOM
  6. SAX
  7. JDOM

Spiele

IDEs

Skriptum

JAVA-DOCS


-----------------
letzte Änderung:
09 December 2021
-----------------
Lehrer Nussbaumers Seite

... in Arbeit ...

DOM

Das Document Object Modell dient zum Verarbeiten von XML-Dateien (XML mit DOM verarbeiten). An dieser Stelle überlgen wir das Parsen und Erstellen von XML-Dateien mit Hilfe der DOM-Schnittstellen in JAVA.

Die verwendete XML-Datei

F&uum;r die weiteren Beispiele dieses Abschnittes verwenden wir folgende XML-Datei:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE weblinks SYSTEM "weblinks.dtd">
<weblinks>
	<eintrag id="0">
		<kategorie>edv</kategorie>
		<url>http://www.w3.org</url>
		<notiz>W3-Konsortium</notiz>
		<notiz>Technische Referenz</notiz>
	</eintrag>
	<eintrag id="1">
		<kategorie>phy</kategorie>
		<url>http://www.cern.ch</url>
		<notiz>Europaeisches Kernforschungszentrum</notiz>
		<notiz>Aktuelles zur Hochenergiephysik</notiz>
		<notiz>Materialien zur Elementarteilchenphysik<notiz>
	</eintrag>
	...
</weblinks>

Wir erkennen eine wohlgeformte XML-Datei, bei der das Wurzelelement <weblinks> alle <eintrag>-Elemente korrekt geschachtelt enthält.

Parsen einer XML-Datei

Um eine XML-Datei parsen zu können, sind folgende Klassen notwendig:

  1. DocumentBuilderFactory
  2. DocumentBuilder

Weiters benötigt man die Interfaces

  1. Document
  2. Node
  3. NodeList

Um mit dem DOM-Parser eine XML-Datei zu parsen, sind daher folgende vier Arbeitsschritte notwendig:

  1. Eine neue Instanz der Klasse DocumentBuilderFactory erzeugen
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance()
  2. Eine Instanz der Klasse DocumentBuilder erzeugen
    DocumentBuilder builder = factory.newDocumentBuilder();
  3. Den XML-Dokumentenbaum parsen und ein document-Objekt erzeugen
    Document document = builder.parse("weblinks.xml");
  4. Die gewünschten Elemente mit geeigneten DOM-Befehlen auswählen.

Beispiel: Alle Kindelemente des Wurzelelementes ausgeben

Das folgende Beispiel dom1.java gibt alle Kindelemente des WUrzelelementes der Datei weblinks.xml aus:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Node;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class dom1 {
    public static void main (String args[]) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse("weblinks.xml");
        NodeList KnotenListe = document.getElementsByTagName("url");
        int anzahl = KnotenListe.getLength();
        for (int i = 0; i < anzahl; i++) {
            System.out.println(KnotenListe.item(i).getFirstChild().getNodeValue());
        }
    }
}

Die gewünschte Knotenliste wird dabei mit Hilfe der Methode getElementsByTagName() erhalten. Aus ihr werden innerhalb der Zählschleife nacheinander alle Knoten ausgewählt. Für jeden Knoten wählt man mit der Methode getFirstChild() der eersten Kindknoten (das ist in "weblinks.xml" jeweils der zum Element "url" enthaltene Text). Den Zeichenkettenwert dieses Textknotens erhält man schließlich mit der Methode getNodeValue().

Das Ergebnis ist eine einfache Liste der gespeicherten Webadressen:

http://www.w3.org
http://www.cern.ch
...

Ist der Knoten wie im vorliegenden Fall ein Textknoten, so kann die Methode getNodeValue() auch wegbleiben. Aufschlussreich ist jedenfalls die folgende Ausgabe:

for (int i = 0; i < anzahl; i++) {
	System.out.println(KnotenListe.item(i));
}

Damit erhält man:

<url>http://www.w3.org<url>
<url>http://www.cern.ch<url>
...

Elemente und Attribute anzeigen

Im folgenden Beispiel sollen Geschwisterelemente ausgegeben werden.

import javax.xml.parsers.*;
import org.w3c.dom.*;

public class dom2 {
    public static void main (String args[]) throws Exception {
        Node Knoten;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse("weblinks.xml");

        NodeList KnotenListe = document.getElementsByTagName("eintrag");
        int anzahl = KnotenListe.getLength();
        for (int i = 0; i < anzahl; i++) {
            Knoten = KnotenListe.item(i);
            System.out.print(Knoten.getChildNodes().item(1).getFirstChild() + "\t");
            System.out.print(Knoten.getChildNodes().item(3).getFirstChild() + "\t");
            System.out.println(Knoten.getChildNodes().item(5).getFirstChild() + "\t");
        }
    }
}

Zunächst werden in diesem Beispiel alle Knoten mit dem Elementnamen "eintrag" ausgewählt. Zu jedem Knoten aus dieser Liste werden nun alle Kindknoten bestimmt, und aus diesen der 1., 3. und 5. Eintrag. Was sind nun die dazwischen liegenden Knoten? Die Lösung sieht man in der dem Beispiel zugrunde liegenden XML-Datei: Der besseren Lesbarkeit halber wurden die einzelnen Elemente mit Zeilenschaltungen und Tabulatoren (white space) gespeichert.

Mit der korrekten Knotenauswahl erhalten wir:

edv     http://www.w3.org       W3-Konsortium
phy     http://www.cern.ch      Europaeisches Kernforschungszentrum

Durch entsprechende Schachtelung lassen sich bestimmte Attribute und Elemente ausgeben. Im folgenden Beispiel werden Elemente und das "id"-Attribut ausgegeben. Mit Hilfe von Zeilenschaltungen ("\n") und Tabulatoren ("\t") wird außerdem eine einfache Formatierung der Ausgabe erreicht...

import javax.xml.parsers.*;
import org.w3c.dom.*;

public class dom3 {
    public static void main (String args[]) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document xmlbaum = builder.parse("weblinks.xml");
        NodeList eintragKnoten = xmlbaum.getElementsByTagName("eintrag");

        int anzahl = eintragKnoten.getLength();
        for (int i = 0; i < anzahl; i++) {
            Element eintrag = (Element) eintragKnoten.item(i);
            String attribut = eintrag.getAttribute("id");
            System.out.print(attribut + ": ");
            NodeList urlKnoten = eintrag.getElementsByTagName("url");
            System.out.println(urlKnoten.item(0).getFirstChild().getNodeValue());
            System.out.println("-------------------------------------");
            NodeList notizKnoten = eintrag.getElementsByTagName("notiz");
            int notizanzahl = notizKnoten.getLength();
            for (int j=0; j<notizanzahl; j++) {
                System.out.print("\t o ");
                System.out.println(notizKnoten.item(j).getFirstChild().getNodeValue());
            }
            System.out.println("=====================================\n");
        }
    }
}

Im Ergebnis lesen wir nach dem id-Attributwert den Zeichenkettenwert des url-Elements und anschließend alle Zeichenkettenwerte der notiz-Elemente:

0: http://www.w3.org
-------------------------------------
         o W3-Konsortium
         o Technische Referenz
=====================================

1: http://www.cern.ch
-------------------------------------
         o Europaeisches Kernforschungszentrum
         o Aktuelles zur Hochenergiephysik
         o Materialien zur Elementarteilchenphysik
=====================================
...

Eine neue XML-Datei erzeugen

Wird eine neue XML-Datei erzeugt, so muss diese noch in eine Textdatei gespeichert werden. Dazu wird der neu erstelle Dokumentenbaum abschließend serialisert:

import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;

public class dom4 {
    public static void main (String args[]) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document xmlbaum = builder.parse("weblinks.xml");
        Document ausgabebaum = builder.newDocument();
        Element wurzel = ausgabebaum.createElement("adressen");
        Element eintrag;
        Element neuElement;

        ausgabebaum.appendChild(wurzel);

        NodeList eintragKnoten = xmlbaum.getElementsByTagName("eintrag");
        int anzahl = eintragKnoten.getLength();
        for (int i = 0; i < anzahl; i++) {
            eintrag = (Element) eintragKnoten.item(i);
            NodeList kategorieKnoten = eintrag.getElementsByTagName("kategorie");
            String vergleich = kategorieKnoten.item(0).getFirstChild().getNodeValue();
            if (vergleich.equals("edv")) {
                NodeList urlKnoten = eintrag.getElementsByTagName("url");
                neuElement = (Element) ausgabebaum.importNode(eintrag, true);
                wurzel.appendChild(neuElement);
            }
        }
        System.out.println(ausgabebaum.getElementsByTagName("adressen").item(0));

        String serial = "<?xml version='1.0' encoding='iso-8859-1' standalone='yes'?>\n";
        serial += ausgabebaum.getElementsByTagName("adressen").item(0);

        try {
            FileWriter Datenstrom = new FileWriter("teil.xml");
            BufferedWriter ausgabe = new BufferedWriter(Datenstrom);
            ausgabe.write(serial);
            ausgabe.flush();
            ausgabe.close();
        }
        catch (IOException e) {
            System.out.println(e);
        }
    }
}

Zu Beginn werden also zwei document-Objekte erzeugt: Das document-Objekt "xmlbaum" enthält die ursprünglichen XML-Elemente. Die document-Methode appendChild() erzeugt für den zunächst leeren XML-Baum "ausgabebaum" das Wurzelelement. Alle Knoten, dessen Kategorie-Element den Wert "edv" hat, werden mit der importNode() - Methode als neues Element für den Ausgabbaum erzeugt. Diese neuen Elemente weren abschließend mit der Element-Methode appendChild()dem Wurzelelement als Kindelemente hinzugefügt.

Bevor wir den XML-Baum in eine Textdatei speichern, geben wir ihn - zur Kontrolle - mit einer einfachen System.out.println()-Anweisung auf der Konsole aus:

<adressen><eintrag id="0">
                <kategorie>edv</kategorie>
                <url>http://www.w3.org</url>
                <notiz>W3-Konsortium</notiz>
                <notiz>Technische Referenz</notiz>
        </eintrag><eintrag id="4">
                <kategorie>edv</kategorie>
                <url>http://www.suse.de</url>
                <notiz>SuSE, Linux</notiz>
                <notiz>Treiber-Datenbank</notiz>
        </eintrag><eintrag id="5">
                <kategorie>edv</kategorie>
                <url>http://www.microsoft.com</url>
                <notiz>Microsoft, Windows</notiz>
                <notiz>Sicherheits-Updates</notiz>
                <notiz>OS-Patches</notiz>
        </eintrag></adressen>

Die gesamte Ausgabe wird zuletzt in eine Stringvariable geschrieben und in der Textdatei "teil.xml" gespeichert. Dabei erhält diese Datei noch die notwendige XML-Deklaration als ersten Eintrag:

<?xml version='1.0' encoding='iso-8859-1'?>
	    <adressen><eintrag id="0">
                <kategorie>edv</kategorie>
                <url>http://www.w3.org</url>
                <notiz>W3-Konsortium</notiz>
                <notiz>Technische Referenz</notiz>
        </eintrag><eintrag id="4">
                <kategorie>edv</kategorie>
                <url>http://www.suse.de</url>
                <notiz>SuSE, Linux</notiz>
                <notiz>Treiber-Datenbank</notiz>
        </eintrag><eintrag id="5">
                <kategorie>edv</kategorie>
                <url>http://www.microsoft.com</url>
                <notiz>Microsoft, Windows</notiz>
                <notiz>Sicherheits-Updates</notiz>
                <notiz>OS-Patches</notiz>
        </eintrag></adressen>


© Alfred Nussbaumer, Weblog "MiniNuss"