Dokumenttypdefinition (DTD)

Eine DTD legt fest, wie sich Elemente innerhalb eines XML-Dokuments aufeinander beziehen. Sie stellt außerdem eine Grammatik für das Dokument und alle seine Elemente zur Verfügung. Ein Dokument, das sich sowohl an die XML-Spezifikationen als auch an die Regeln hält, die von seiner DTD umrissen werden, wird als gültig bezeichnet (im Gegensatz zu einem wohlgeformten Dokument, das sich nur an die XML-Syntaxregeln hält).

Dokumenttyp-Deklaration:

Sie informiert den XML-Prozessor darüber, welche Dokumenttyp-Definition (DTD) für die folgende Instanz gültig ist und wo sich die Datei mit der DTD befindet (externe DTD) oder wie die DTD aussieht (interne DTD). Die DTD ist damit ein Bestandteil der Dokumenttyp-Deklaration.

Aufbau:

Im Folgenden geht es um den Aufbau der DTD. Ob es sich dabei um eine externe oder interne DTD (oder eine Kombination aus beidem) handelt, spielt an dieser Stelle keine Rolle. Informell ist es ganz leicht, den Inhalt einer DTD zu erklären : Sie enthält die Informationen darüber, welche Elementtypen es gibt, welchen Inhalt sie haben dürfen, welche Attribute erlaubt sind und welche Werte sie annehmen dürfen.

Elementtyp-Deklaration:

Die wichtigste Komponente der DTD, die Elementtyp-Deklaration, besitzt folgende Gestalt:
<!ELEMENT Elementname Regel >
Dies deklariert ein XML-Element und eine mit diesem Element assoziierte Regel, die das Element logisch in das XML-Dokument einbezieht. Der Elementname darf die Zeichen <> nicht umfassen. Ein Elementname muß mit einem Buchstaben oder einem Unterstrich beginnen. Anschließend kann eine beliebige Anzahl von Buchstaben, Zahlen, Bindestrichen, Punkten oder Unterstrichen im Namen stehen. Elementnamen dürfen nicht mit der Zeichenkette XML beginnen, weder in Groß- noch in Kleinschreibung oder irgendeiner Variation davon. Ein Doppelpunkt in einem Elementnamen darf nur als Trennzeichen zwischen einem Namensraum und dem eigentlichen Elementnamen benutzt werden, ansonsten ist die Benutzung eines Doppelpunktes verboten.
Folgende Beispiele sollen einen Eindruck von Elementtyp-Deklarationen geben:

<!ELEMENT adresse1 (vorname, nachname, strasse, ort)>

<!ELEMENT adresse2 (anrede?, vorname, nachname, strasse, ort)>

<!ELEMENT adresse3 ((firma | person), strasse, ort)>
<!ELEMENT firma       (firmenname)>
<!ELEMENT person    (anrede?, vorname, nachname)>

<!ELEMENT adressbuch (adresse)+>

<!ELEMENT adressbuch (adresse)*>

Das Repertoire zur Definition des Inhaltes zeigen im Wesentlichen die obigen Beispiele. Der Reihe nach: Eine adresse1 besteht einfach aus der Folge vorname, nachname, strasse, ort. Das Komma zwischen den Elementen ist der so genannte Sequenz-Operator.
Die Variante adresse2 stellt eine optionale Anrede voran. Das Fragezeichen ist hier das wichtigste Zeichen. Es bedeutet, dass die anrede fehlen darf.
Das letzte Adresstyp-Beispiel, adresse3, kann sogar mit Firmen- und Privat-adressen umgehen (Gruppierung). Diese Flexibilität verdankt es dem Oder-Operator, der als senkrechter Strich geschrieben wird. In diesem Fall kann man zwischen einer Firma und einer Person wählen.
Die letzten zwei Beispiele sind alternative Formen eines Adressbuchs. Bei der Variante mit dem Pluszeichen muss ein Adressbuch mindestens eine Adresse enthalten.
Der Stern in der zweiten Adressbuch-Version bedeutet, dass beliebig viele Adressen aufeinander folgen dürfen. Im Unterschied zum Pluszeichen darf das Buch hier auch leer sein. "Beliebig viele" heißt also 0 oder 1 oder 2 oder ...
Für komplexere Elementinhalte können die Operatoren kombiniert werden.

Attribut Beschreibung
? Muß einmal oder überhaupt nicht auftauchen
+ Muß mindestens einmal auftauchen
* Kann keinmal oder mehrmals auftauchen


Inhalte, die nicht nur aus Elementen bestehen (ANY und PCDATA)

Die einfachste Elementdeklaration drückt aus, dass zwischen dem Start- und dem Ende-Tag eines Elements alles mögliche erscheinen kann :
<!ELEMENT library ANY>
Durch die Benutzung des Schlüsselworts ANY dürfen sowohl andere gültige Tags als auch allgemeine Zeichendaten innerhalb des Elements verwendet werden. Es kann jedoch auch eine Situation vorkommen, wo nur allgemeine Zeichendaten erscheinen sollen. Diese Art von Daten ist besser unter der Benennung als analysierte Zeichendaten (parsed character data), oder kurz PCDATA, bekannt. Mit der folgenden Deklaration kann man festlegen, dass ein Element nur PCDATA enthält:
<!ELEMENT title (#PCDATA)>
Zu beachten ist, dass diese Deklaration bedeutet, dass alle Zeichendaten, die kein Element sind, zwischen den Element-Tags auftauchen können. Deswegen ist es erlaubt, folgendes in dem XML-Dokument zu schreiben:
<title></title>
<title>XML in der Praxis</title>
Dagegen ist das folgende Element mit der obigen PCDATA-Deklaration falsch:
<title>
 XML <emphasis>in der Praxis</emphasis>
</title>

Leere Elemente

Man muß auch jedes leere Element, das innerhalb eines gültigen XML-Dokuments benutzt werden soll, in der DTD deklarieren. Dies geschieht mit dem Schlüsselwort EMPTY:
<!ELEMENT Elementname EMPTY>
Beispielsweise definiert die folgende Deklaration ein Element in dem XML-Dokument, das als <hr/> oder <hr></hr> benutzt werden kann:
<!ELEMENT hr EMPTY>
Ähnlich wie etwa das img aus HTML.

Attributlisten-Deklaration

Eine Attributlisten-Deklaration legt fest, welche Attribute für einen Elementtyp existieren, von welchem Typ die Attributwerte sind, und ggf. enthält sie einen Vorgabe-Wert (default). Man kann alle Attribute mit der Deklaration <!ATTLIST> definieren, die in der folgenden Form benutzt wird:
<!ATTLIST Ziel-Element Attribut Datentyp Default-Wert>
Die folgenden Beispiele zeigen Attribute, die in HTML vorkommen:
<!ATTLIST img
  src      CDATA  #REQUIRED
  alt       CDATA  #REQUIRED
  height  CDATA  #IMPLIED
  width   CDATA #IMPLIED
>

<!ATTLIST h1
  id     ID   #IMPLIED
  align (left | center | right | justify) left
>

Die beiden notwendigen (REQUIRED) Attribute src und alt erwarten beide eine Zeichenkette als Wert (CDATA). Gleiche Wertetypen sind für die Höhen- und Breitenangabe erlaubt, jedoch müssen diese Werte nicht explizit angegeben werden.
Für den HTML-Elementtyp h1 sind im Beispiel zwei weitere Attributtypen zu sehen: id dient dazu, eine eindeutige Identifikation an einem Element anzubringen. Auf so ein Element kann mit einem Attribut vom Typ idref verwiesen werden. Das zweite Attribut von h1, align, ist vom Typ Aufzählungstyp. Der Wertebereich dieses Typs ist vollständig in den Klammern enthalten. Andere Werte als die dort gezeigten sind nicht zugelassen. Die Vorgabe ist in diesem Fall der Wert left.
Default-Modifikatoren in DTD-Attributen:

Modifikator Beschreibung
#REQUIRED Der Attributwert muß mit dem Element angegeben werden.
#IMPLIED Der Attributwert kann unspezifiziert bleiben.
#FIXED Der Attributwert ist festgelegt und kann vom Anwender nicht verändert werden.

Mit dem Schlüsselwort #IMPLIED muß der XML-Parser, wenn der Wert nicht angegeben ist und auch im XML-Dokument kein Wert angegeben ist, der Anwendung mitteilen, dass kein Wert angegeben worden ist. Die Anwendung kann dann verwenden, was immer sie bei diesem Punkt für geeignet hält. Mit dem Schlüsselwort #FIXED muß der Default-Wert sofort anschließend angegeben werden:
<!ATTLIST date year CDATA #FIXED "2001">

Parameter-Entities:

Parameter-Entity-Referenzen werden nur in DTDs verwendet und werden ersetzt durch ihre entsprechenden Entity-Definitionen in der DTD. Alle Parameter-Entity-Referenzen fangen mit einem Prozentzeichen an, was zudem deutlich macht, dass Parameter-Entity-Referenzen nicht in einem XML-Dokument benutzt werden können - nur in der DTD, in der sie definiert werden. Eine Parameter-Entity wird wie folgt definiert:
<!ENTITY % Name "Ersetzungszeichen">

<!ENTITY % block "absatz | listing | abbildung | kasten ">

<!ELEMENT buch               (kapitel+)>
<!ELEMENT kapitel            (ueberschrift, (%block;)*, abschnitt+)>
<!ELEMENT abschnitt         (ueberschrift, (%block;)*, unterabschnitt*)>
<!ELEMENT unterabschnitt  (ueberschrift, (%block;)+)>
In obigem Beispiel gibt es mehrere Textblöcke, die im Inhaltsmodell dreier Elementtypen auftreten. Auf den ersten Blick ist damit nur eine kürzere Schreibweise erzielt worden. Sollten nun aber Änderungen anstehen, wie etwa das Hinzufügen eines Blockelements Tabelle, so muss lediglich die Definition des Entity geändert werden. Neben der leichteren Wartbarkeit einer DTD erhöht sich durch den sinnvollen Einsatz von Entities auch die Lesbarkeit.

Externe-Entities:

In XML deklariert man externe Entities in der folgenden Syntax:
<!ENTITY quotes SYSTEM "http://www.boerse.com/stocks/quotes.xml">
Auf diese Weise kann man den XML-Inhalt einer externen Datei (angegeben durch den entsprechenden URI) mittels einer externen Referenz in das XML-Dokument kopieren. Zum Beispiel:
<document>
  <heading>Current Stock Quotes</heading>
  &quotes;
</dokument>
Dieses Beispiel kopiert den XML-Inhalt, der sich hinter dem URI http://www.boerse.com/stocks/quotes.xml verbirgt, in dem Moment in das XML-Dokument, wenn es im XML-Prozessor verarbeitet wird. Dies ist besonders bei der Verarbeitung von dynamischen Daten sehr nützlich.

Datentypen:

Typ Beschreibung
CDATA Zeichendaten
Aufzählungstyp Eine Aufzählung von Werten, aus der nur ein einziger Wert gewählt werden kann.
ENTITY Eine Entity, die in der DTD deklariert wird.
ID Ein eindeutiges Elementkennzeichen
IDREF Der Wert eines eindeutigen ID-Typattributs.