Titel   Inhalt   Suchen   Index   DOC  Handbuch der Java-Programmierung, 7. Auflage
 <<    <     >    >>   API  Kapitel 43 - XML-Verarbeitung

43.1 XML-Grundlagen



XML ist die Abkürzung für »eXtensible Markup Language«. Dabei handelt es sich um ein universelles, textbasiertes Datenformat, das hauptsächlich zur Speicherung und zum Transfer von Daten verwendet wird. XML-Dokumente sind selbst beschreibend und sowohl menschen- als auch maschinenlesbar. Außerdem sind sie interoperabel, also unabhängig von Betriebssystemen und Rechnerarchitekturen. XML ist mächtig und ausdrucksstark, gleichzeitig ist es relativ leicht zu erlernen, zu erzeugen und zu interpretieren und hat sich daher in der digitalen Welt rasant verbreitet. XML entstand durch die Weiterentwicklung des SGML-Standards unter der Führung von John Bosac. Es ist ein offener Standard des W3C-Konsortiums, dessen erste Version 1998 veröffentlicht wurde.

Mittlerweile gibt es im Umfeld von XML eine ganze Reihe weiterer Standards und es hat sich eine regelrechte Industrie rund um die Sprache entwickelt. Einige der Standards im XML-Universum sind beispielsweise:

Auch als Grundlage unternehmensspezifischer proprietärer Sprachen ist XML weit verbreitet und fast jedes Standardprogramm bietet mittlerweile Schnittstellen zum Lesen und Schreiben von XML-Daten.

43.1.1 Aufbau eines XML-Dokuments

Wir wollen uns zunächst ansehen, wie XML-Dokumente aussehen und welchen Aufbau sie haben. Eine Datei, die dem XML-Standard folgt, wird »XML-Dokument« genannt; das folgende Listing zeigt ein einfaches Beispiel:

001 <?xml version="1.0" encoding="iso-8859-15"?> 
002 <gruss> 
003   Hallo, Welt!
004 </gruss>
Listing 43.1: Ein einfaches XML-Dokument

Offenbar besteht das Dokument aus zwei verschiedenen Bestandteilen. Einerseits erkennen wir mit Hallo, Welt! rein textuelle Teile, die »einfach so« aufgeschrieben werden, andererseits mit <gruss> oder </gruss> befehlsartige Elemente, die in spitze Klammern gesetzt werden.

Konkret lässt sich die Syntax eines XML-Dokuments vereinfacht wie folgt angeben:

xml     : [ prolog ] element 
element : <tag> [ ( inhalt | element+ ) ] </tag>

Ein XML-Dokument beginnt optional mit einem Prolog, darauf folgt ein Element, das sogenannte Wurzelelement. Elemente können weitere Elemente oder Text enthalten und werden von einem öffnenden und einem schließenden Tag eingeschlossen. Wir wollen uns die einzelnen Bestandteile eines XML-Dokuments in den nächsten Abschnitten genauer ansehen.

Prolog

In der ersten Zeile von Listing 43.1 sehen Sie den optionalen »Prolog«, mit dem die Datei als XML-Dokument gekennzeichnet wird. Der Prolog beginnt mit der Zeichenfolge <?xml und endet mit ?>. Er bestimmt mindestens die XML-Version (version="1.0") und besitzt optional weitere Attribute, wie beispielsweise das Encoding des Dokuments (encoding="iso-8859-15"). Wird die Encoding-Angabe weggelassen, wird als Zeichensatz UTF-8 bzw. UTF-16 angenommen.

Grundsätzlich sind alle Zeichensätze erlaubt, die von der IANA (Internet Assigned Numbers Authority) definiert wurden (siehe http://www.iana.org/assignments/character-sets). Zu den wichtigsten in unserem Sprachraum gehören windows-1252 und iso-8859-15 sowie utf-8 bzw. utf-16.

Die IANA-Encoding-Namen entsprechen nicht den Namen der Zeichensätze unter Java. Der Windows-Standardzeichensatz heißt unter Java beispielsweise cp1252, im IANA-Standard aber windows-1252. Außerdem arbeiten die Betriebssysteme und Editoren oftmals nicht mit dem XML-Standardzeichensatz UFT-8 oder UTF-16, sondern mit dem Standardzeichensatz des jeweiligen Betriebssystems. Daher empfiehlt es sich, das Encoding in jedem XML-Dokument explizit anzugeben. Andernfalls führt z.B. die Verwendung von Umlauten in der Praxis schnell zu Problemen.

 Hinweis 

Elemente

Jedes XML-Dokument besitzt genau ein Wurzelelement, das wiederum kein, ein oder mehrere andere Elemente enthalten kann. Jedes Element kann seinerseits Attribute haben und sowohl Text als auch weitere Unterlemente enthalten. Auf diese Weise lassen sich hierarchische, baumartige Datenstrukturen erzeugen.

Ein Element besteht aus einem öffnenden und einem schließenden »Tag«. Ein Tag hat einen festen Namen und wird in spitze Klammern gesetzt. Das öffnende Tag wird mit < und > umschlossen, das schließende Tag mit </ und >. Listing 43.1 enthält beispielsweise genau ein Element mit dem Namen gruss, das in diesem Beispiel den Text Hallo, Welt! enthält.

Das folgende Beispiel zeigt ein zweistufig hierarchisches Dokument mit dem Wurzelelement gruesse.

001 <?xml version="1.0" encoding="iso-8859-15"?> 
002 <gruesse> 
003   <gruss bundesland="schleswig-holstein"> 
004     Moin, moin!
005   </gruss> 
006   <gruss bundesland="bayern"> 
007     Grüß Gott!
008   </gruss> 
009 </gruesse>
Listing 43.2: Ein zweistufiges, hierarchisches XML-Dokument

Das gruesse-Element enthält zwei gruss-Elemente und jedes gruss-Element besitzt ein bundesland-Attribut. Enthält ein Element keinen Text und keine weiteren Elemente, kann es in Kurzschreibweise geschrieben werden. Der Tagname wird dann von < und /> umschlossen:

<tag/>

001 <?xml version="1.0" encoding="iso-8859-15"?> 
002 <geschlecht> 
003   <maennlich/> 
004 </geschlecht>
Listing 43.3: Beispiel für die Kurzschreibweise

Attribute

Elemente können eine beliebige Anzahl von Attributen besitzen, mit deren Hilfe sie konfiguriert werden können. Das gruss-Element in Listing 43.2 enthält beispielsweise das Attribut bundesland, mit dem die regionale Variante der Grußformel ausgewählt wird. Attribute werden immer im öffnenden Tag angegeben und bestehen aus einem Namen und einem Wert. Mit Attributen lassen sich spezifische Eigenschaften eines Elements genauer beschreiben.

Kommentare

Kommentare sind fester Bestandteil der XML-Grammatik. Sie beginnen mit der Zeichenfolge <!-- und enden mit -->. Kommentare sind nicht schachtelbar, aber sie dürfen sich über mehrere Zeilen erstrecken. Die Zeichenfolge -- ist in Kommentaren nicht erlaubt.

<!-- Kommentar -->

001 <?xml version="1.0" encoding="iso-8859-15"?> 
002 <!-- Gruss an die Welt --> 
003 <gruss> 
004   Hallo, Welt!
005 </gruss>
Listing 43.4: Ein einfaches XML-Dokument mit Kommentar

43.1.2 Document Type Definition

Fester Bestandteil des XML-Universums ist die Möglichkeit, mit Hilfe einer Grammatik den strukturellen Aufbau von XML-Dokumenten zu definieren. Grammatiken werden entweder mit einer DTD (Document Type Definition) oder mit einer XSD (XML Schema Definition) beschrieben. XSD ist selbst ein umfangreicher XML-Dialekt und es lassen sich damit sehr präzise Grammatiken entwerfen. DTDs sind der ältere Standard, sie stammen im Grundsatz noch aus der SGML-Ära. Sie sind weniger aufwändig als XSDs, für viele praktische Anwendungsfälle aber ausreichend. Weil DTDs einfacher zu erlernen und zu entwerfen sind als XSDs, wollen wir uns zunächst den Umgang mit DTDs ansehen.

Zum Verständnis der folgenden Ausführungen sind zwei Begriffe bedeutsam. Ein XML-Dokument heißt »wohlgeformt« (»wellformed«), wenn es lexikalisch korrekt ist, also den im vorigen Abschnitt beschriebenen Aufbau besitzt. Ein XML-Dokument heißt »gültig« (»valid«), wenn es wohlgeformt ist UND seiner Grammatik genügt.

Damit ein XML-Dokument ordnungsgemäß verarbeitet werden kann, muss es mindestens wohlgeformt sein, eine Grammatik dagegen ist nicht zwingend erforderlich. Diese empfiehlt sich aber immer dann, wenn das Dokument komplex ist oder als Schnittstelle zwischen verschiedenen Systemen oder Personen dient. Eine explizite Grammatik stellt nicht zuletzt auch ein wichtiges Stück Dokumentation dar.

Aufbau einer DTD

DTDs selbst sind keine XML-Dokumente, sehen auf den ersten Blick aber ein wenig so aus. Auch eine DTD beginnt beispielsweise zunächst mit einem optionalen XML-Prolog, hinter dem die Definition der Elemente und Attribute folgt. DTDs können auch Kommentare enthalten, sie haben genau den gleichen Aufbau wie Kommentare in einem XML-Dokument.

Als erstes Beispiel sehen wir uns eine DTD für Listing 43.1 an:

001 <?xml version="1.0" encoding="iso-8859-15"?>
002 <!ELEMENT gruss (#PCDATA)>
Listing 43.5: DTD des XML-HelloWorld-Beispiels

In der ersten Zeile sehen Sie den XML-Prolog, gefolgt von der Defintion des einzigen Elements gruss. Das gruss-Element kann Text enthalten, was durch die Formulierung #PCDATA zum Ausdruck gebracht wird.

Elementdefinition

In der Elementdefinition wird festgelegt, ob das Element Text aufnehmen oder andere Elemente enthalten soll. Zudem muss zu jedem Kindelement die Häufigkeit des Auftretens festgelegt werden. Die Elementdefintion beginnt mit <!ELEMENT, gefolgt von dem Namen des Elements. Nach dem Namen folgt der mögliche Inhalt des Elements. #PCDATA signalisiert, dass das Element Text enthalten kann. Enthält das Element andere Elemente, werden diese in runden Klammern aufgezählt. Die Reihenfolge der Elemente ist dabei von Bedeutung, d.h., die Elemente müssen später in dem XML-Dokument in der festgelegten Reihenfolge auftreten. Die Defintion eines Elements endet mit >.

001 <!-- Ein oder mehrere gruss-Kinder -->
002 <!ELEMENT gruesse (gruss+)>
003 
004 <!-- Kein, ein oder mehrere gruss-Kinder -->
005 <!ELEMENT gruesse (gruss*)>
006 
007 <!-- Ein gruss-Kind -->
008 <!ELEMENT gruesse (gruss)>
009 
010 <!-- gruss enthält einen lang- und einen kurztext -->
011 <!ELEMENT gruss (langtext, kurztext)>
012 
013 <!-- Entweder maennlich oder weiblich -->
014 <!ELEMENT geschlecht (maennnlich | weiblich)>
015 
016 <!-- gruss enthält Text -->
017 <!ELEMENT gruss (#PCDATA)>
Listing 43.6: DTD-Elemente

Die Häufigkeit des Auftretens jedes Elements wird durch die angehängten Symbole +, * usw. bestimmt. Ein + bedeutet, dass ein Element ein- oder mehrere Male auftreten darf, ein * steht für beliebig häufiges Auftreten und ein ? bedeutet, dass das Element entweder gar nicht oder genau einmal auftreten kann. Werden mehrere Unterelemente mit Kommata getrennt, müssen sie auch im XML-Dokument in genau dieser Reihenfolge auftreten. Werden sie mit einem senkrechten Strich getrennt, muss genau eines der aufgelisteten Elemente an der entsprechenden Stelle auftauchen.

Attributdefinition

Die Attributdefinition beginnt mit <!ATTLIST, gefolgt von dem Elementnamen, zu dem das Attribut gehört, gefolgt von dem Namen des Attributs selbst Das Schlüsselwort CDATA signalisiert, dass das Attribut beliebigen Text enthalten kann. Das Attribut kann optional (#IMPLIED) oder obligatorisch (#REQUIRED) sein. Kann ein Attribut nur eines von wenigen zuvor festgelegten Werten annehmen, werden diese in runden Klammern aufgezählt und mit | voneinander getrennt. Die Defintion des Attributs endet mit >.

Das folgende Listing zeigt die DTD von Listing 43.2.

001 <?xml version="1.0" encoding="iso-8859-15"?>
002 <!ELEMENT gruesse (gruss+)>
003 <!ELEMENT gruss (#PCDATA)>
004 <!ATTLIST gruss bundesland CDATA #REQUIRED>
Listing 43.7: DTD zum Dialekt-Beispiel

Das folgende Listing zeigt weitere Attributdefinitionen:

001 <!-- Attribut mit Defaultwert -->
002 <!ATTLIST auto anzahlreifen CDATA "4">
003 
004 <!-- Obligatorisches Attribut -->
005 <!ATTLIST gruss bundesland CDATA #REQUIRED >
006 
007 <!-- Optionales Attribut -->
008 <!ATTLIST gruss bundesland CDATA #IMPLIED >
009 
010 <!-- Attribut mit Auswahlliste -->
011 <!ATTLIST person geschlecht (maennlich|weiblich) "maennlich" >
Listing 43.8: DTD-Attribute

Einbinden einer DTD

Soll ein XML-Dokument validiert werden können, muss es den Zusammenhang zur DTD selbst herstellen. Eine DTD kann entweder direkt in das XML-Dokument eingebettet sein oder als externe Datei referenziert werden. Da es in der Praxis meist üblich ist, die DTD extern zu definieren, wollen wir auf die internen DTDs an dieser Stelle nicht weiter eingehen. Das XML-Dokument verweist auf seine externe DTD im Anschluss an die Prologzeile:

001 <?xml version="1.0" encoding="iso-8859-15"?> 
002 <!DOCTYPE gruss SYSTEM "gruss.dtd"> 
003 <gruss> 
004 Hallo, Welt!
005 </gruss>
Listing 43.9: HelloWorld mit externer DTD

In der Doctype Definition wird das Wurzelelement, also das Element der höchsten Ebene, angegeben (in unserem Fall gruss). Danach folgt das Schlüsselwort SYSTEM und der Dateiname der DTD. Bevor wir uns nun der eigentlichen programmgesteuerten Verarbeitung der XML-Dokumente zuwenden, wollen wir noch kurz auf die zweite Form der XML-Grammatiken eingehen, die XML Schema Definitionen.

43.1.3 XML Schema Definition

Die »XML Schema Definition«, kurz XSD, ermöglicht ebenfalls die Definition von XML-Grammatiken. Im Gegensatz zu DTDs sind XSD-Dateien selbst XML-Dokumente, die ihrerseits einer Grammatik folgen. Die XML Schema Definition bietet im Gegensatz zur DTD mehr Freiheitsgrade und unterscheidet diverse elementare Datentypen. Außerdem erlaubt sie es, einfache und komplexe Datentypen selbst zu definieren. Die ausführliche Beschreibung der XML Schema Definition ist für den Rahmen dieser Einführung viel zu umfangreich, wir wollen uns daher im Folgenden lediglich einige Grundlagen dieses Standards ansehen.

Eine XSD-Datei beginnt wie folgt:

<?xml version="1.0" encoding="iso-8859-15"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
Listing 43.10: Beginn einer XSD-Datei

Den Prolog kennen wir aus Abschnitt 43.1.1. Im schema-Wurzelelement verbinden wir den Präfix xs mit der Grammatik der XML Schema Definition. Der Name des Präfixes ist frei wählbar, meist wird xs verwendet, gelegentlich auch xsd. Der Präfix (Namensraum) wird u.a. den Elementnamen vorangestellt, gefolgt von einem :. In unserem Fall lautet der komplette Präfix also xs:.

Elementdefinition

Elemente definiert man wie folgt:

<xs:element name="name">

Mit dem Attribut name wird der Name des zu definierenden Elements festgelegt. Ein weiteres wichtiges, aber optionales Attribut ist type zur Definition des Datentyps des Elementinhalts.

<xs:element name="name" type="type">

Die XML Schema Definition bietet eine Reihe elementarer Datentypen an, von denen die wichtigsten in der folgenden Tabelle aufgeführt sind:

Name Beschreibung
boolean Wahrheitswert, repräsentiert durch den Ausdruck false bzw. true oder durch die Zahlen 0 und 1
byte Ein acht Bit langer Ganzzahltyp, entsprechend dem Wertebereich des Java-Datentyps byte
date Darstellung eines Datums, optional mit Zeitzone. Beispiel: 1972-03-03
dateTime Darstellung eines Datums inkl. Zeitangabe, optional mit Zeitzone. Beispiel: 1969-07-20T03:40:00
double Eine 64 Bit-Fließkommazahl nach IEEE 754, entprechend dem Wertebereich des Java-Datentyps double
float Eine 32 Bit-Fließkommazahl nach IEEE 754, entsprechend dem Wertebereich des gleichnamigen Java-Datentyps
int Eine 32 Bit-Ganzzahl, entsprechend dem Wertebereich des Java-Datentyps int
short Darstellung einer 16 Bit-Ganzzahl, entsprechend dem Wertebereich des gleichnamigen Java-Datentyps
string Darstellung einer beliebigen Zeichenkette, entsprechend dem Java-Datentyp String
time Darstellung einer Uhrzeitangabe. Beispiel: 23:59:59

Tabelle 43.1: Wichtige elementare Datentypen des XSD-Standards

Einige Beispiele dazu:

001 <!-- Element mit ganzzahligem Inhalt -->
002 <element name="anzahl" type="xs:int"/>
003 
004 <!-- Element mit Uhrzeit-Inhalt -->
005 <element name="abfahrt" type="xs:time"/>
006 
007 <!-- Element mit Zeichenketten-Inhalt -->
008 <element name="vorname" type="xs:string"/>
Listing 43.11: Elementdefinitionen

Elemente, die andere Elemente enthalten, heißen komplexe Elemente und werden wie folgt definiert:

001 <?xml version="1.0" encoding="iso-8859-15"?>
002 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
003   <xs:element name="gruesse">
004     <xs:complexType>
005       <xs:sequence>
006         <xs:element name="gruss" type="xs:string"/>
007      </xs:sequence>
008     </xs:complexType>
009   </xs:element>
010 </xs:schema>
Listing 43.12: XSD-Wurzelelement mit genau einem Kind

In diesem Beispiel enthält das gruesse-Element genau ein gruss-Kind; im folgenden Listing kann es kein, ein oder mehrere Kinder enthalten:

001 <?xml version="1.0" encoding="iso-8859-15"?>
002 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
003   <xs:element name="gruesse">
004     <xs:complexType>
005       <xs:sequence>
006         <xs:element name="gruss" type="xs:string" 
007            minOccurs="0" maxOccurs="unbounded"/>
008      </xs:sequence>
009     </xs:complexType>
010   </xs:element>
011 </xs:schema>
Listing 43.13: XSD-Wurzelelement mit beliebig vielen Kindern

Die Attribute maxOccurs und minOccurs haben die Voreinstellung 1. Statt in einem sequence-Element können Sie die Kindelemente auch mit einem all- (beliebige Reihenfolge der Kindelemente) oder choice-Element (nur ein Kindelement) umschließen.

Attributdefinition

Elemente, die Attribute enthalten, heißen ebenfalls komplexe Elemente und werden so definiert:

001 <?xml version="1.0" encoding="iso-8859-15"?>
002 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
003   <xs:element name="gruesse">
004     <xs:complexType>
005       <xs:sequence>
006         <xs:element name="gruss" maxOccurs="unbounded"> 
007           <xs:complexType>
008             <xs:simpleContent>
009               <xs:extension base="xs:string">
010                 <xs:attribute name="bundesland" type="xs:string"/>
011               </xs:extension>
012             </xs:simpleContent>
013           </xs:complexType>
014         </xs:element> 
015      </xs:sequence>
016     </xs:complexType>
017   </xs:element>
018 </xs:schema>
Listing 43.14: XSD-Attribute

Das vorangegangene Beispiel zeigt eine gültige XSD für das XML-Dokument in Listing 43.2. In Zeile 006 bis Zeile 014 wird das gruss-Kindelement deklariert. Das Element soll Inhalte vom Typ String enthalten. Dies können wir aber an dieser Stelle nicht über das type-Attribut am gruss-Element ausdrücken, weil es ein complexType-Element enthält. Mit dem extension-Element leiten wir es stattdessen von einem Element ab, das einen String aufnehmen kann. Außerdem definieren wir ein bundesland-Attribut, das Inhalte vom Typ String aufnehmen kann.

Kommentare

Da XML Schema Definitionen XML-Dokumente sind, kann man natürlich normale XML-Kommentare verwenden. In XSDs gibt es einen weiteren Weg, der es im Gegensatz zu den normalen XML-Kommentaren ermöglicht, Kommentare maschinell zu verarbeiten, denn es handelt sich um normale Elemente. Das ist beispielsweise praktisch, um aus einer XML Schema Definiton eine Dokumentation zu generieren:

001 <?xml version="1.0" encoding="iso-8859-15"?>
002 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
003   <xs:element name="gruesse">
004     <xs:annotation>
005       <xs:documentation xml:lang="DE">
006       Grüße in verschiedenen Bundesländern
007       </xs:documentation>
008     </xs:annotation>
009     ...
010   </xs:element>
011 </xs:schema>
Listing 43.15: XSD-Kommentare

Einbinden einer XSD

Wie bei einer DTD muss auch ein XSD-validierbares XML-Dokument den Zusammenhang zu seiner Grammatik selbst herstellen. Das XML-Dokument referenziert dazu seine XSD im Wurzelelement. Im folgenden Beispiel wird die XSD so eingebunden, dass man den Elementen keinen Namesraum-Präfix voranstellen muss:

001 <?xml version="1.0" encoding="UTF-8"?>
002 <gruesse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
003          xsi:noNamespaceSchemaLocation="gruesse.xsd">
004 ...
Listing 43.16: Einbinden einer XSD


 Titel   Inhalt   Suchen   Index   DOC  Handbuch der Java-Programmierung, 7. Auflage, Addison Wesley, Version 7.0
 <<    <     >    >>   API  © 1998, 2011 Guido Krüger & Heiko Hansen, http://www.javabuch.de