5. Mit DOM auf XML-Tags zugreifen

Nachdem Sie im letzten Kapitel den DOM-Parser und die entsprechenden Klassen sowie Interfaces kennen gelernt haben, werden wir in diesem Kapitel auf die Tags einer XML-Datei zugreifen. Als XML-Datei für dieses Kapitel verwenden wir die Beispieldatei aus dem Kapitel "DOM und XML", die mehrere Datensätze enthält. Die XML-Datei sieht folgendermaßen aus:

<?xml version="1.0" encoding="ISO-8859-1"?>

<Adresse>

<Datensatz>

<Nachname>Schwarz</Nachname>

<Vorname>Sabine</Vorname>

<Strasse>Blauweg 4</Strasse>

<PLZ>53000</PLZ>

<Ort>Bonn</Ort>

<Telefon>0228-99999999</Telefon>

</Datensatz>

<Datensatz>

<Nachname>Blau</Nachname>

<Vorname>Sabine</Vorname>

<Strasse>Rotweg 4</Strasse>

<PLZ>53000</PLZ>

<Ort>Bonn</Ort>

<Telefon>0228-88888888</Telefon>

</Datensatz>

<Datensatz>

<Nachname>Schröder</Nachname>

<Vorname>Sabine</Vorname>

<Strasse>Grünstraße 4</Strasse>

<PLZ>53000</PLZ>

<Ort>Bonn</Ort>

<Telefon>0228-777777777</Telefon>

</Datensatz>

</Adresse>

Das Wurzelelement der Datei ist <Adresse>. Unterhalb dieses Tags befinden sich drei Tags <Datensatz>, die jeweils die Tags <Nachname>, <Vorname>, <Strasse>, <PLZ>, <Ort> und <Telefon> enthalten.

5.1. Ein XML-Tag ansprechen

Jetzt wird es spannend: Wir wollen einen einfachen Code konstruieren, der konkret auf ein XML-Tag und dessen Inhalt zugreift. Dies geschieht natürlich über die DOM-Methoden und über das Objekt document des Interface Document. DOM kennt folgende wichtige Methoden, die ein XML-Tag ansprechen und die im Interface Document enthalten sind:

  • getElementById(): spricht ein XML-Tag anhand des vergebenen Attributs ID an.
  • getElementsByTagName(): spricht ein XML-Tag auf der Basis des Tagnamens an.

Hinweis: DOM definiert noch die Methode getElementsByName(). Diese Methode spricht ein Tag anhand des vergebenen Attributs NAME an. Diese Methode ist ein DOM-Standard, jedoch wurde diese Methode nicht in JAXP (und damit auch nicht in J2 SE 1.4) implementiert.

Am sinnvollsten ist bei XML der Einsatz der DOM-Methode getElementsByTagName(). Denn oftmals wird in den XML-Tags kein Attribut ID vergeben, sodass die Methode getElementById() nicht eingesetzt werden kann. getElementsByTagName() ermittelt dabei sämtliche gefundenen XML-Tags, die diesen Namen tragen. Der Rückgabewert ist ein Array, denn es können in einer XML-Datei ja mehrere Tags dieses Namens vorkommen.

Für das nachfolgende Beispiel werden wir als XML-Datei die Datei daten.xml verwenden, die auch schon im Kapitel "DOM und XML" zum Einsatz kam. Hier finden sich drei Tags <Datensatz>, die alle über die Tags <Nachname>, <Vorname>, <Strasse> usw. verfügen. Im ersten Schritt wollen wir das Tag <Vorname> ansprechen und die Anzahl der gefundenen Tags <Vorname> ausgeben.

Der Programmcode

Der Code muss vor dem Ende der Klammern der main()-Methode um folgende drei Zeilen erweitert werden:

NodeList tagliste=document.getElementsByTagName ("Vorname");

int anz=tagliste.getLength();

System.out.println("Anzahl des Tags <vorname>"+anz );

Der Java-Code

Das eingelesene XML-Dokument liegt ja in dem Objekt document vor. Auf dieses wird nun die Methode getElementsByTagName() eingesetzt. In Klammern wird der Tagname angegeben. Die Methode erwartet immer einen String als Übergabeparameter. Der Rückgabewert ist ein Array und hier konkret ein Objekt des Interface NodeList. Das Interface NodeList enthält nichts anderes als eine Liste der gefundenen Tags dieses Namens. Die einzelnen Tags sind über die Indexnummer zugänglich, die Zählung beginnt bei 0. Die Methode getLength() des Interface NodeList ermittelt die Anzahl der gefundenen Einträge.

Der einzelne Knoten

Um jetzt jedes einzelne Tag anzusprechen, muss die Methode item() und die Indexnummer verwendet werden:

Node das_tag;

int a;

String Name_des_Tags;

for (a=0; a<anz; a++)

{

das_tag=tagliste.item(a);

Name_des_Tags=das_tag.getNodeName();

System.out.println("Tagname: "+Name_des_Tags);

}

Die Liste mit den gefundenen Tags – die so genannte Knotenliste (engl., Nodelist) – wird in der for-Schleife durchlaufen. Das Objekt das_tag ist ein Objekt des Interface Node. Diese Klasse stellt ein konkretes XML-Tag dar und spricht eines der Tags aus der Knotenliste an. Genauer gesagt ist es ein Knoten, d.h. ein XML-Tag, das über Unter-Tags verfügt. a ist eine Zählervariable und Name_des_Tags der ausgelesene Tagname. In der for-Schleife wird aus der Liste der gefundenen XML-Tags jedes einzelne Tag ausgelesen. Dazu wird die Methode item() verwendet und die Indexnummer an diese übergeben. Diese Methode ist in dem Interface NodeList enthalten und muss natürlich auf das Objekt tagliste angewendet werden. Der Rückgabewert ist ein Objekt des Interface Node, d.h. das konkrete XML-Tag. Um den Tagnamen auszulesen ist die Methode getNodeName() erforderlich, die den Namen des Nodes (d.h. des Tags) ausliest. Der Rückgabewert ist ein String, der dann ausgegeben werden kann.

Der Inhalt eines Knotens

Nachdem wir jetzt das Tag, d.h. den Knoten, in einem Objekt gespeichert haben, fehlt noch der konkrete Inhalt des Tags. Der Inhalt eines Knotens kann selbst ja wieder ein Node sein. In unserem Beispiel mit der kleinen XML-Datenbank ist es "normaler" Text, d.h., das Tag <Vorname> enthält einen Text. Um den Inhalt auszugeben, sind zwei Schritte nötig:

  • In das entsprechende Tag reingehen.
  • Den Inhalt auslesen.

Dieses Vorgehen wird durch zwei Methoden des Interface Node realisiert:

  • getFirstChild()
  • getNodeValue()

Die Methode getFirstChild() ermittelt den Node, der sich in dem Tag befindet. Dies könnte ein anderes Tag sein, aber auch "normaler" Text. Auch ein solcher normaler Text ist ein Node. Da es sich in unserer XML-Datenbank um Text handelt, können wir sofort über die Methode getNodeValue() den Text auslesen:

NodeList tagliste=document.getElementsByTagName("Vorname");

int anz=tagliste.getLength();

System.out.println("AnzahlTags <vorname>: "+anz);

Node das_tag;

int a;

String Name_des_Tags, inhalt;

for (a=0; a<anz; a++)

{

das_tag=tagliste.item(a);

Name_des_Tags=das_tag.getNodeName();

inhalt=das_tag.getFirstChild().getNodeValue();

System.out.println("Tagname: "+Name_des_Tags+

" Inhalt: "+inhalt);

}

Die Methode getNodeValue() liefert einen String zurück, dessen Ergebnis wir in inhalt speichern. Die Methode ist in Node definiert und kann daher nur auf ein Objekt des Interface Node angewendet werden. Die Methode getFirstChild() liefert konkret den ersten Node innerhalb des Tags <Vorname> zurück. Dies ist der Text, d.h. ein Text Node (Textknoten). Die Methode getFirstChild() können Sie auf jedes XML-Tag anwenden, der Rückgabewert ist immer ein Node.

Der Knotentyp

Im nächsten Schritt können wir den Inhaltstyp des XML-Tags feststellen. Diese Information ist wichtig, denn ein XML-Tag kann einen Text enthalten (so genannter Text Node), aber auch weitere Tags (so genannter Element Node). Der Code des vorherigen Abschnitts wird hier erweitert:

short TagTyp, ChildTyp;

for (a=0; a<anz; a++)

{

das_tag=tagliste.item(a);

Name_des_Tags=das_tag.getNodeName();

TagTyp=das_tag.getNodeType();

inhalt=das_tag.getFirstChild().getNodeValue();

ChildTyp=das_tag.getFirstChild().getNodeType();

System.out.println("Tagname: "+Name_des_Tags+

" Typ: "+TagTyp+" Inhalt: " +

inhalt+" Typ: "+ChildTyp);

}

Vor der for-Schleife werden die beiden Variablen TagTyp und ChildTyp definiert. Der Datentyp ist jeweils short. Die Methode getNodeTyp() ermittelt den Inhaltstyp des Tags und ist in Node enthalten. Interessant ist nun die Ausgabe, diese ist für jedes XML-Tag 1. Dies bezeichnet den Typ des Tags. Es ist ein so genannter ELEMENT_NODE, d.h. ein "normales" XML-Tag. Dieses kann einen Inhalt besitzen, z.B. einen "normalen" Text. Dieser ist wiederum ein Node, der dann vom Inhaltstyp 3 (so genannter TEXT_NODE) wäre. Der Nodetyp wird als Zahl zwischen 1 und 12 zurückgegeben. Es handelt sich um Klassenvariablen, die im Interface Node definiert sind. Einen Überblick über das Interface Node und dessen Klassenvariablen finden Sie im Kapitel "Die Interfaces" im Abschnitt "Das Interface Node".

Nächster Schritt: Eine grafische Ausgabe
Vorheriger Schritt: Attribute berücksichtigen

(Hinweis: Dies ist ein Text von Michael Seeboerger-Weichselbaum. Der Text stammt aus dessem Buch "Java/XML - Das Einsteigerseminar" aus dem mi-Verlag (ISBN 3-8266-7208-9). Das Urheberrecht liegt bei Michael Seeboerger-Weichselbaum)

© msw 1999-2005