0251 / 590 837 15
info@a-coding-project.de

XML: Document Type Definition (DTD)

Eine Document Type Definition (DTD) ist die Grundlage für jedes XML-Dokument. Innerhalb dieser DTD wird die genaue Struktur, die Anordnung und der Inhalt sowie die Attribute mit ihren möglichen Werten genau definiert.

Was ist eine DTD und wie schreibe ich sie?

Eine DTD ist, wie gesagt, die Beschreibung der Inahlte einer XML-Datei. Die XML-Spezifikation beschreibt dafür genaue Mechanismen wie eine DTD definiert werden muss und wie man sie verwendet. Im Allgemeinen gesehen ist eine DTD jedoch nichts weiter als eine Datei im Text-Format mit der Dateiendung .dtd. Ebenso wie sie auch XML-Dokumente erstellen können Sie dafür einen Text-Editor oder einen speziellen DTD-Editor verwenden. Letztere bergen meist den Vorteil, dass bei der Erstellung einer DTD nicht viel falsch gemacht werden kann (siehe Abschnitt DTD-Software).

Wie ist eine DTD aufgebaut?

Der Syntax einer DTD sieht in etwa aus wie eine Menge Kommentare und DOCTYPE-ähnlichen Tags. Es werden also wieder Tags verwendet. Allerdings besteht dennoch ein gewisser Unterschied in der Schreibweise. Eine DTD beinhaltet allgemein zwei Typen von Tags: Element- und Attributdeklarationen. Des Weiteren können noch Notationen, Kommentare, ein- und ausgeschlossene Abschnitte sowie Entitäten durch bestimmte Tags eingebunden oder definiert werden.

Elementdeklarationen

Eine Elementdeklaration definiert, dass es in jedem XML-Dokument, welches diese DTD verwendet, dieses bestimmte Element geben kann. Darüber hinaus bestimmt die Deklaration den Inhalt des Elementes sowie dessen Häufigkeit.

Eine Elementdeklaration wird immer durch den folgenden Syntax ausgedrückt:

<!ELEMENT Name Inhalt >

... wobei Name der Name des Elementes ist und durch Inhalt der Inhalt näher beschrieben wird. Der Name kann, wie im Abschnitt "Tags, Elemente und Attribute" bereits beschrieben, relativ frei gewählt werden. Bei der Namensvergabe und anschließender Verwendung sollten Sie allerdings darauf achten, dass Sie die richtige Schreibweise einbehalten. Das heißt: XML unterscheidet zwischen Groß- und Kleinschreibung. Definieren Sie ein Element MeinElement, dann ist das nicht gleichbedeutend mit meinelement.

Der Inhalt eines Elementes kann durch mehrere Dinge definiert sein. Zum Einen können die Namen der Elemente die es enthalten darf notiert werden. Soll beispielsweise das Element Person enthalten sein dürfen, dann schreiben Sie:

<!ELEMENT MeinElement Person >

Zum Zweiten können bestimmte Anweisungen definiert werden, die je nach dem eine andere Bedeutung für den Inhalt des Dokumentes darstellen. Drei Anweisungen stehen zur Auswahl:

AnweisungBedeutung
ANYJedes beliebige Element und Zeichen darf verwendet werden.
EMPTYDas Element darf keinen Inhalt haben.
#PCDATAEs dürfen nur geparste Zeichen verwendet werden. D.h. keine Elemente.
Soll ein Element also keine Elemente enthalten dürfen (also als leeres Element fungieren), könnten wir das so notieren:

<!ELEMENT MeinElement EMPTY >

Als drittes dürfen in der Inhaltsangabe eines Elementes bestimmte Zeichen vorkommen, die die Häufigkeit und sogar Reihenfolge definieren. Dazu stehen folgende Zeichen bzw. Schreibweisen zur Auswahl:

ZeichenBedeutung
( x )Zwei Klammern um einen Ausdruck fügen diesen zu einer Einheit zusammen (ähnlich anderen Programmiersprachen).
,Werden mehrere Elemente oder Typen in einer durch Kommatas getrennten Liste aufgeführt müssen diese Elemente - sofern keine tieferen Bestimmungen vorliegen - in exakt dieser Anzahl und Reihenfolge vorkommen.
|Der Abwärtstrich bedeutet ein logisches ODER. D.h. entweder das Element bzw. der Typ vor oder der danach müssen vorkommen.
?Das Fragezeichen bedeutet, dass ein Element keinmal oder einmal vorkommen darf.
*Der Stern beutet, dass ein Element keinmal, einmal oder mehrmals vorkommen darf.
+Das Pluszeichen bedeutet, dass ein Element ein- oder mehrmals vorkommen darf.

<!ELEMENT Kunde (Name, (Besuch, Datum)+) >
<!ELEMENT Person (Name, Adresse, Nummer) >
<!ELEMENT Adresse ((Straße, Ort, PLZ) | Postfach) >
<!ELEMENT Person (Vorname, Titel?, Nachname) >
<!ELEMENT Adressbuch (Person*) >
<!ELEMENT Person (Name, Adresse+) >

Soll ein Element sowohl #PCDATA als auch ein Element enthalten, muss auf die Reihenfolge geachtet werden. Bei solchen gemischten Elementen ist es zwingend notwendig, dass der #PCDATA-Aufruf am Anfang steht und alle weiteren Elemente nur durch ein ODER (|) getrennt werden - andere Zeichen sind hierbei nicht möglich. Des Weiteren muss die Definition eingeklammert werden und einen Stern (*) nach der schließenden Klammer erhalten. Letztlich ergibt sich für gemischte Elemente immer folgendes Schema:

<!ELEMENT Name (#PCDATA | Elemente)* >

Attributdeklarationen

Bei der Attributdeklaration verhält es sich in etwa wie bei der Elementdeklaration. Sie beschreibt die Eigenschaften die ein Element erhalten darf/muss, deren Werte und Wertetypen sowie einen eventuellen Standard-Wert. Zur Deklaration von Attributen wird der folgende Syntax verwendet:

<!ATTLIST Elementname Attributdefinitionen>

... wobei der Elementname exakt mit einem definierten Element übereinstimmen muss. Als Attributdefinitionen können beliebig viele Definitionen dem Elementnamen folgen. Jede Definition besteht aus vier hintereinander stehenden Werten die in der Reihenfolge den Attributnamen, den Wertetyp, den Status des Attrubutes sowie einen Standardwert angeben.

Der Attributname unterliegt den gleichen beschränkungen wie auch Elementnamen und kann damit weitestgehend frei gewählt werden. Ihm folgt der Attributtyp. Dieser kann aus folgenden Definitionen bestehen:

  • CDATA - Der Wert kann beliebige geparste Zeichen enthalten.
  • ENTITY - Der Wert kann einen allgemeinen ungeparsten Entity enthalten.
  • ENTITIES - Der Wert kann einen oder mehrere Entity's enthalten (durch Leerzeichen getrennt).
  • ID - Der Wert kann einen beliebigen Wert erhalten der in innerhalb des Dokuments eineindeutig identifizierbar macht. Der Wert darf nicht doppelt im Dokument vorkommen.
  • IDREF - Der Wert kann die ID eines anderen Elements annehmen.
  • IDREFS - Der Wert kann einen oder mehrere ID's anderer Elemente enthalten (durch Leerzeichen getrennt).
  • NMTOKEN - Der Wert kann einen gültigen XML-Namen enthalten (z.B. einen Elementnamen).
  • NMTOKENS - Der Wert kann einen oder mehrere gültige XML-Namen enthalten (durch Leerzeichen getrennt).
  • NOTATION - Der Wert kann den Namen einer Notation enthalten.
  • ( x | y ) - Der Wert kann entweder den Wert x (ein definierter Wert) oder y (ebenso ein definierter Wert) annehmen. Auch eine Mehrfachauswahl ist möglich.
Anschließend kann optional der Status des Attributes und/oder folgend der Standardwert definiert werden. Als Standardwert wird einfach ein möglicher Wert in Anführungszeichen notiert. Als Status stehen 3 zur Auswahl:

  • #FIXED - Der Standardwert gilt als einziger möglicher Wert. Es muss dazu ein Standardwert definiert werden.
  • #IMPLIED - Besagt, dass ein XML-Interpreter der Anwendung mitteilen muss, dass ein oder kein Wert angegeben wurde bzw. welcher Wert angegeben wurde.
  • #REQUIRED - Das Attribut muss unbedingt bei jedem Auftreten des Elements definiert werden.
Letztlich könnten sich z.B. folgende Attributdefinitionen ergeben:

<!ATTLIST Mitglied Name CDATA
                   Vorname CDATA #IMPLIED
                   Beitrag (bezahlt | nichtbezahlt) "bezahlt"
>
<!ATTLIST Datenbank Typ CDATA #REQUIRED "MySQL">
<!ATTLIST Datenbank Inhalt IDREFS>

Bitte beachten Sie, dass es beliebig ist, in welcher Reihenfolge und Art Sie die Attribute definieren. Des Weiteren ist es auch möglich mehrere ATTLIST's für ein Element zu definieren.

Standard-Attribute

Standard-Attribute sind Attribute die durch XML speziell definiert sind und nur zu besonderen Zwecken verwendet werden können/sollten. Diese sind xml:space und xml:lang. Das xml:space-Attribut beschreibt, wie mit Whitspaces (Tabulator, Wagenrücklauf, Zeilenvorschub, Leerzeichen) umgegangen werden soll. Es sollte als mögliche Werte default und preserve erhalten. Der Wert default besagt, dass mit Whitespaces normal verfahren werden soll - d.h. mehrere Whitespaces werden zu einem zusammen gefasst. Der Wert preserve dagegen besagt, dass alle enthaltenen Whitespaces erhalten bleiben sollen und kein Zusammenfassen vorgenommen werden soll. Wird das Attribut nicht definiert, gilt für alle Elemente standardmäßig default. Beispiel:

<!ATTLIST MeinElement xml:space (default | preserve) #IMPLIED "default">

Das zweite Attribut ist xml:lang und enthält einen Wert vom Typ NMTOKEN. Es steht für die verwendete Sprache innerhalb des Elementes. Als Werte sollen hier alle durch ISO 3166 oder die IANA beschriebenen Ländercodes gelten (de, fr, en, de-CH, usw.). Es ergibt sich die folgende Definition des Attributes:

<!ATTLIST MeinElement xml:lang NMTOKEN #IMPLIED>

Bedingte Abschnitte

Ein- oder ausgeschlossene Abschnitte (auch bedingte Abschnitte genannt) sind Abschnitte innerhalb einer internen oder externen DTD die explizit in eine bestimmte Menge ein- bzw. ausgeschlossen werden sollen. Der Vorteil solcher Abschnitte liegt im Zusammenhang mit Entity's. Wird eine Entity als ausgeschlossener Abschnitt definiert, brauch nur die Entity geändert werden um sämtliche ausgeschlossene Abschnitte in die DTD aufzunehmen (ebenso bei eingeschlossenen Abschnitten). Ein eingeschlossener Abschnitt beginnt immer mit <![INCLUDE[ und endet mit ]]>. Ausgeschlossen wird beginnent durch <![IGNORE[ und endent mit ]]>. Dazwischen können sich alle beliebigen Definitionen von Elementen, Attributen oder Kommentaren (usw.) befinden. Das folgende Beispiel soll, neben der Verwendung dieser Abschnitte, gleichzeitig die Verwendung mit Entity's verdeutlichen:

<!-- normale Definition: -->
<![INCLUDE[
  <!ELEMENT MeinElement >
  <!-- ... weiteres ... -->
]]>
<![IGNORE[
  <!ELEMENT MeinElement >
  <!-- ... weiteres ... -->
]]>

<!-- Verwendung mit Entity's: -->
<!ENTITY % entwurf 'IGNORE' >
<!ENTITY % fertig 'INCLUDE' >

<![%entwurf;[
  <!ELEMENT MeinElement (A, B, C, D)>
]]>
<![%fertig;[
  <!ELEMENT MeinElement (A, B, C)>
]]>

Beim Beispiel der Verwendung mit Entity's brauchen nun nur noch die Entity's vertauscht werden, damit alle im Entwurf befindlichen Deklarationen anstelle der bereits fertigen Deklarationen verwendet werden.

Notationen

Notationen bezeichnen ein Nicht- XML-Format. Ein interpretierendes Programm weiß so, dass es diese Daten nicht zu parsen braucht. Eine Notation wird immer nach dem folgenden Schema notiert:

<!NOTATION Name Typ Programm>

Der Name einer Notation beschreibt einen Entity mit dessen Hilfe das Format eingefügt werden soll. Der Typ kann entweder SYSTEM oder PUBLIC sein. Ähnlich wie bei DOCTYPE beschriebt dieser, ob es sich um ein öffentliches (PUBLIC) oder nicht öffentliches (SYSTEM) Format handelt. Anschließend folgt eine Kennzeichnung, die es dem Interpreter erlaubt ein geeignetes Programm zum Ausführen der Daten zu finden. Ein Beispiel für die Verwendung von JPEG-Dateien:

<!NOTATION JPEG SYSTEM "Jpeg">
<!ENTITY MeinEntity SYTEM "bild.jpeg" NDATA JPEG>

Entity's

Entity's sind bestimmte Bezeichner, die es erlauben bestimmte Strings (~Text) innerhalb einer XML-Datei oder DTD durch einen anderen zu ersetzen. Die Entity definiert dazu den orginal String und den String, der stattdessen eingesetzt werden soll. Man unterscheidet Entity's in 2 mal 2 Gruppen: Parameter und allgemeine Entity's sowie jeweils in externe und interne Entity's. Allgemeine Entity's fügen einen bestimmten Text oder Datei in ein XML-Dokument ein - Parameter Entity's in eine DTD. Im Grunde besitzen alle Entity-Deklarationen den folgenden Syntax:

<!ENTITY Name Status Ersatz>

Allgemeine Entity's werden immer mit einem Kaufmanns-Und (&) vor sowie einem Semikolon (;) nach dem Namen aufgerufen (&Name;). Bei der Definition des Namens werden diese Merkmale allerdings nicht mitgeschrieben. Beispiel:

<!ENTITY MeinName "Max Mustermann">
<!ENTITY Datei1 SYSTEM "meinedatei1.xml">
<!ENTITY ExternA PUBLIC "-//Meine//Beschreibung//DE" "http://www.name.de/abc.xml">

Wie Sie wahrscheinlich dem Beispiel entnehmen können, handelt es sich einen internen (erster) und zwei externe (zweiter und dritter) Entity's. Bei internen Entity's wird dieser bei jedem Aufruf des Entity's innerhalb eines XML-Dokumentes durch den definierten Text (hier Max Mustermann) ersetzt. Bei externen Entity's verhält sich das ebenso, nur dass hierbei der Entity-Aufruf durch eine Datei ersetzt wird. Ebenso wie bei DOCTYPE kann hier zwischen öffentlichen (PUBLIC/dritter) und nicht öffentlichen (SYSTEM/zweiter) Dateien unterschieden werden. Bei öffentlichen muss dazu allerdings vor derURLdie allgemeine Bezeichnung der Datei angegeben werden (dritter). Beispiel für den Aufruf:

<?xml version="1.0"?>
<!DOCTYPE Text [
 <!Element Text #PCDATA>
 <!ENTITY MeinName "Max Mustermann">
]>
<Text>
 Hallo ich bin &MeinName;!
</Text>

Parameter Entity's werden immer mit einem Prozentzeichen (%) vor sowie einem Semikolon (;) nach dem Namen aufgerufen (%Name;). Bei der Definition des Entity's wird diese Schreibweise allerdings so nicht ganz übernommen: Man schreibt das Prozentzeichen, ein Leerzeichen und anschließend den Namen (ohne Semikolon). Beispiel:

<!ENTITY % MeinName "(true | false)">
<!ENTITY % Datei1 SYSTEM "meinedatei1.mod">
<!ENTITY % ExternA PUBLIC "-//Meine//Beschreibung//DE" "http://www.name.de/abc.mod">

Im Beispiel wurde ein interner Parameter Entity (erster) und zwei externe Parameter Entity's definiert. Diese können insich durchaus mit den allgemeinen Entity's gleichgesetzt werden, nur eben mit dem Unterschied, dass sie nur innerhalb von DTD's verwendet werden dürfen und einen leicht anderen Syntax benutzen. Die im Beispiel definierten Entitys fügen anstelle der Aufrufe %MeinName;, %Datei1; und %ExternA; die bestimmten Texte ((true | false)) bzw. Dateien (meinedatei1.mod und .../abc.mod) in eine DTD ein. Beispiel für den Aufruf:

<!ENTITY % wert "(true | false)">
<!ATTLIST MeinElement MeinAttribut %wert; "true">

Kommentare in DTD's

Kommentare werden in DTD's ebenso wie in XML-Dokumenten notiert. Das heißt sie beginnen mit <!-- und enden mit -->. Beispiel:

<!ELEMENT MeinElement>
<!--das ist mein Element!-->

DTD-Software

Ebenso wie es spezielle XML-Software gibt, gibt es auch Software speziell zum Erstellen und Bearbeiten von DTD's. Sehr empfehlenswert ist hierbei EzDTD. Zu finden unter: http://www.geocities.com/SiliconValley/Haven/2638/ezDTD.htm.