XML Elemente

Elemente sind die einfachsten und häufigsten Bestandteile von XML. Jedes XML-Dokument hat EIN Wurzelelement, das alle anderen Elemente enthält.

<?xml version="1.0"?>
<buch>Der Herr der Ringe</buch>
<autor>
<vorname>John Ronald Reuel</vorname>
<nachname>Tolkien</nachname>
</autor>

Dieses Beispiel wäre also KEIN wohlgeformtes XML-Dokument, da es zwei Wurzelelemente (oder, je nach Betrachtungsweise, kein Wurzelelement) besitzt, nämlich <buch> und <autor>.

Grundsätzlich gibt es zwei verschiedene Elemente: nichtleere und - welch Wunder - leere. Für die leeren Elemente gibt es zwei Schreibweisen, die völlig gleichwertig sind. Es ist also euch überlassen, welche Notation ihr verwenden wollt.

<nichtLeer>Inhalt</nichtLeer>

<leeresElement></leeresElement>
<leeresElement2/>

In XML gilt die Regel, daß zu jedem öffnenden Tag auch ein schließendes Tag existieren muß. Das schließende Tag wird duch den Schrägstrich gekennzeichnet. Die Ausnahme ist die zweite Variante des leeren Elements. Hier werden quasi öffnendes und schließendes Tag zusammengefaßt.

Diejenigen unter euch, die auch geistig noch folgen (jaja, ich weiß. das Thema ist trocken und der Geist ist schläfrig), werden sich jetzt vielleicht fragen, wo der Sinn von leeren Elementen liegt. Dieser wird wahrscheinlich erst mit dem Lesen des nächsten Kapitels (Attribute) klar. Als kleine Vorwegname sei hier das <img> Tag aus HTML genannt. Dieses ist ja auch ein leeres Element.

Nun ist das ja alles schön und gut. Aber wie kann ich denn nun ein Element in der DTD definieren? Dazu muß man erstmal wissen, daß (logischerweise nichtleere) Elemente unterschiedliche Inhalte haben können: Text, weitere Elemente oder beides.

<!ELEMENT name (#PCDATA)>

definiert ein Element name, das nur Text (parsed character data) enthalten darf. ACHTUNG: In XML werden Groß- und Kleinschreibung unterschieden. Also ist name nicht gleich Name!

<!ELEMENT titel (#PCDATA)>
<!ELEMENT autor (#PCDATA)>

<!ELEMENT buch (titel, autor)>

Hier werden zwei Elemente titel und autor definiert (beide Text). Das Element buch wird so definiert, daß es in den XML-Dokumenten dann diese beiden Elemente in dieser Reihenfolge genau einmal enthalten muss. Man kann also Anzahl und Reihenfolge der Child-Elemente bestimmen.

Was nun aber, wenn man keine Abfolge von Elementen (Sequenz) festlegen will, sondern eine Auswahl (beispielsweise könnte sich eine Adresse entweder auf eine Person, oder auf eine Firma beziehen)? Die Lösung kommt in Form des Operators | daher. Einigen von euch wird das Teil schon bekannt sein, da es auch an verschiedenen anderen Stellen vorkommt. Und wie nicht anders zu erwarten, ist das auch in XML ein "oder".

<!ELEMENT anschrift (firma | name), strasse, ort, email>

<!ELEMENT firma (#PCDATA)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT strasse (#PCDATA)>
<!ELEMENT ort (#PCDATA)>
<!ELEMENT email (#PCDATA)>

In diesem Beispiel können wir also zwischen einem Firmennamen und dem Namen einer Person wählen, müssen dann aber Straße, Ort und email Adresse angeben. Nun, daß Leben ist ungerecht. Und so gibt es Menschen mit mehreren email Adressen, und auch welche ohne (ja, auch das gibt es!). Um dem gerecht zu werden, gibt es folgende Operatoren:

? Das Objekt ist optional, kann also null oder einmal auftreten.
* Das Objekt ist optional, kann aber beliebig oft auftreten.
+ Das Objekt muß mindestens einmal auftreten.

Unser Beispiel sollte also besser so aussehen:

<!ELEMENT anschrift (firma | name), strasse, ort, email*>

Die Definition der restlichen Elemente hab ich mir hier gespart, sie verändern sich ja nicht.

An dieser Stelle möchte ich noch einmal verdeutlichen, daß, wenn keiner der oben genannten Operatoren verwendet wird, das Element genau einmal vorkommen muß.

Ein Elementtyp ist jetzt noch ungeklärt: gemischter Inhalt (mixed content). Gemischter Inhalt bedeutet, daß das Element Text und weitere Elemente enthalten soll. Für diesen Fall gelten einige Besonderheiten bei der Definition:

  • #PCDATA muß immer an erster Stelle stehen
  • alle Inhalte müßen mit | verknüpft werden
  • die gesamte Gruppe muß optional sein, und beliebig oft vorkommen dürfen (also der *-Operator)

Im Klartext bedeutet das, daß man weder die Anzahl noch die Reihenfolge der Inhalte eines Elements mit mixed content bestimmen kann. Daher ist nach folgender DTD

<!ELEMENT zitat (#PCDATA)>
<!ELEMENT text (#PCDATA | zitat)*> 

dieses XML-Dokument gültig (valide):

<text>
Heinz Rühmann sagte:
<zitat> Ein Pessimist ist ein Mensch, der sich über schlechte
Erfahrungen freut, weil sie ihm Recht geben.
</zitat>
Aber das ist nur eins von vielen Zitaten über Pessimisten.
</text>

So weit so gut, mit den Elementen sind wir fast durch (freut euch des Lebens, denn es ist Licht am Ende des Tunnels!). Eine Frage bleibt noch: Wie zum Geier kann man leere Elemente definieren??? So:

<!ELEMENT leer EMPTY>

Klingt plausibel, gelle? Analog zu EMPTY gibt es auch noch das Schlüsselwort ANY. Das bedeutet zu unser aller Erstaunen, daß das entsprechende Element alle in der DTD definierten Elemente und PCDATA in jeder Reihenfolge und Anzahl enthalten kann. Also können wir unser Zitat-Text-Beispiel noch einmal vereinfachen:

<!ELEMENT zitat (#PCDATA)>
<!ELEMENT text ANY>

Nun, da ihr bis hier durchgehalten habt, habt ihr das Kapitel Elemente eigentlich geschafft. Wenn ihr allerdings kein photographisches Gedächtnis habt, oder sonst irgendwie von der Natur bevorzugt wurdet, habt ihr wahrscheinlich schon wieder vergessen, was am Anfang des Kapitels stand. Es wäre deshalb vielleicht nicht schlecht, noch ein umfassendes, zusammenfassendes, umwerfend einfaches, einprägsames, kurzes, Verständis förderndes, abschließendes Beispiel zu bringen. Zumindest letzteres Kriterium kann ich ohne Probleme erfüllen.

Stellen wir uns vor, wir wollen Bücher in XML-Dokumenten fassen. Zu jedem Buch soll der Titel, und der Inhalt gespeichert werden. Der Inhalt gliedert sich in Kapitel, und diese wiederum in Überschriften, Text und Zitate. Die Anzahl und Reihenfolge von Texten und Zitaten soll beliebig sein. Mir ist klar, daß dieses Modell eines Buches im Höchstmaße unbefriediegend ist. Seht es als Herausforderung, und definiert eine bessere DTD!

<!ELEMENT buch (titel, kapitel+)>      <!--ein Titel, min. ein Kapitel-->

<!ELEMENT titel (#PCDATA)>
<!ELEMENT kapitel (headline, (text | zitat)*)>
<!--zuerst immer die Überschrift, dann Text/Zitate in beliebiger Folge-->

<!ELEMENT headline (#PCDATA)>
<!ELEMENT text (#PCDATA)>
<!ELEMENT zitat (#PCDATA)>

Ein XML-Dokument diesen Typs könnte vielleicht so aussehen:

<?xml version="1.0"?>
<!DOCTYPE buch SYSTEM "buch.dtd">

<buch>
<titel>Mein erstes Buch</titel> <kapitel> <headline>Einleitung</headline>
<text>
Einleitungen sind immer ein sehr schwieriger Teil. Und damit
jetzt auch noch ein Zitat in dieses Beispiel kommt:
</text>
<zitat>
Optimisten glauben, daß wir in der besten aller Welten leben.
Pessimisten befürchten, daß das stimmt.
</zitat> <text>
Nun kann man hier noch 'ne Menge Text schreiben, muß man aber
nicht. Auch das Zitieren wäre nach Lust und Laune möglich. Nur Überschriften dürfen nicht mehr kommen.
</text>
</kapitel>
</buch>

zurück                weiter

nach oben