DTD: Regeln für XML-Dokumente

09.10.2000 von Holger Reibold
XML-basierte Inhalte verlangen nach Regeln, die festlegen, welche Tags in welcher Form verwendet werden dürfen. Diese Aufgabe erledigt die Dokumententyp-Definition DTD.

Eine der herausragenden Eigenschaften von XML ist seine Flexibilität: Jeder Entwickler kann nach Belieben eigene Tags einführen oder beinahe beliebig Attribute vergeben. Will man jedoch zwischen verschiedenen Softwarepaketen XML-Daten austauschen, müssen die Dokumente eben doch gewissen Regeln entsprechen. Irgendwie muss also festgelegt werden, welche Tags zulässig sind und welche nicht. Genau das ist Aufgabe der Dokumententyp-Definition - kurz DTD. DTDs sind formale Spezifikationen aller in einem Dokumenttyp erlaubten Strukturen. Man spricht auch von einer formalen Grammatik, in der zulässige Tags, Attribute und deren Verschachtelung definiert sind. Erst DTDs geben dem Ganzen also eine sinnvolle Bedeutung.

So wie jede natürliche Sprache ein Regelwerk benötigt, das festlegt, wie Sätze konstruiert, und Wörter und Begriffe aneinander gereiht werden können, so benötigen auch Auszeichnungssprachen eine Grammatik. In DTDs werden zulässige Elementnamen, deren möglichen Eigenschaften und deren Attribute definiert. Sie stellen somit sicher, dass verarbeitende Anwendungen XML-Dokumenten entsprechend der zu Grunde liegenden Grammatik interpretieren und verstehen können.

Einziger Haken: Die DTDs hat XML von SGML geerbt. Die dahinter stehende Technik unterliegt beispielsweise bei der Verwendung von Datentypen diversen Beschränkungen. Noch schlimmer ist, dass DTDs keine XML-Syntax verwenden. Diese Einschränkungen löst der DTD-Nachfolger XML-Schemata.

Jeder nutzt DTDs

Ob bewusst oder unbewusst: Im Internet stößt man ständig auf die so genannten Dokumententyp-Definitionen (document type definition, DTD). Dazu reicht ein Blick in den Quellcode typischer HTML-Dokumente: Zumeist beginnen sie mit der Referenzierung einer dieser Definitionen. Wie die Bezeichnung DTD schon besagt, beschreibt sie Dokumententypen. "Klassische" HTML -Dokumente, SGML - oder XML -basierte Inhalte nutzen diesen Mechanismus, um die Zugehörigkeit von Dokumenten zu einer bestimmten Dokumentengruppe zu beschreiben. Dokumententyp-Definitionen liefern gewissermaßen die Grammatik, die bestimmt, welche (strukturellen) Elemente verwendet werden dürfen.

Im Web findet man unterschiedlichste Beispiele für diese Dokumentgruppen:

Die tecChannel-Seiten legen die DTD der HTML-3.2-Spezifikation zu Grunde. Klicken Sie beispielsweise beim Internet Explorer auf Ansicht/Quelltext anzeigen, finden Sie zu beginn einer jeden tecChannel-Seite folgende Zeile:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">

Die Website der W3-Konsortiums verwendet eine XHTML-1.0-DTD:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Auf anderen Seiten findet man auch die Referenzierung der HTML-4.0-DTD:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

In allen drei Beispielen handelt es sich um standardisierte Dokumententyp-Definitionen, wie sie in den zugehörigen Spezifikationen definiert sind.

XML versus HTML

HTML hat im Gegensatz zu XML einen entscheidenden Nachteil. HTML versucht, mit einer einzigen Definition die Struktur von Dokumenten zu beschreiben. Ein aussichtsloses Unterfangen, denn zu unterschiedlich sind die Strukturen von privaten Homepages, kommerziellen Shopping-Seiten oder webbasierten Animationen, als dass ein solcher Ansatz in der Praxis funktionieren könnte.

Nicht zuletzt wegen solcher Unzulänglichkeiten ist XML entstanden. XML erlaubt jedem Entwickler, eigene Dokumententyp-Definitionen zu generieren, also eigene strukturelle Grundlagen für die jeweilige Anwendung zu definieren.

XML hat den DTD-Mechanismus von SGML geerbt. Prinzipiell kommen XML-Dokumente auch ohne eine DTD aus. Damit XML-basierte Inhalte aber sinnvoll zu verarbeiten sind, müssen den eingeführten Tags Beschränkungen hinsichtlich der Reihenfolge und Verschachtelungen auferlegt werden. Diese Beschränkungen realisieren unterschiedliche Deklarationen.

Allgemeiner formuliert: DTDs verwenden Deklarationen, die es Dokumenten ermöglichen, Meta-Informationen über die Inhalte an das zu verarbeitende Programm, den Parser , zu übergeben. Meta-Informationen schließen die erlaubte Reihenfolge und Verschachtelungen von Tags, Attributwerte, Typ und Standardwerte ein.

Logische und physikalische Struktur

DTDs beschreiben alle Aspekte, wie Tags innerhalb von Dokumenten verwendet werden dürfen. Sie definieren, welche Elemente verfügbar sind, in welcher Reihenfolge diese erscheinen müssen und welche Verschachtelungen möglich sind. XML-Dokumente, die sich an die Vorgaben der DTD halten, bezeichnet man als gültig.

Der Begriff "Struktur" ist grundlegend für das Verständnis von DTDs. Prinzipiell muss man zwischen logischen und physikalischen Strukturen unterscheiden. Logische Strukturen definieren die strukturelle Abfolge von Elementen im Dokument. Hier eignet sich wieder das Bild des Baumes, das aus genau einem Wurzelelement besteht, an dem beliebig viele Unterbäume hängen. Diese Unterbäume bestehen selbst aus Elementen. Diesen Elementen lassen sich Attribute zuordnen. Aus dieser Betrachtungsweise folgt: Logische Strukturen bestehen aus Elementtyp- und Attributlisten-Deklarationen.

Die physikalische Struktur von XML-Dokumenten ist durch die Speicherungseinheiten, so genannte Entitäten, gegeben. Ein XML-Dokument kann aus einer oder mehreren Entitäten bestehen. Da XML-Dokumente nicht nur Textstrukturen beschreiben, sondern ebenso multimediale Inhalte (also auch Nicht-XML-Inhalte) einbinden, werden diese über externe Entitäten deklariert. Eine entsprechende Notation beschreibt dabei das Datenformat einer externen Entität. Eine solche Notation kann beispielsweise einen Hinweis auf ein externes Programm beinhalten, das den Inhalt der Entity verarbeitet. Physikalische Strukturen werden also durch Entity- und Notation-Deklarationen definiert.

Referenzierung

Die anfangs aufgeführten Beispiele zeigen, wie die Referenzierung von DTDs in HTML- und XHTML-Dokumenten aussieht. Nicht viel anders verhält es sich bei XML-Dokumenten. Im Prolog eines XML-Dokuments wird angeben, ob einem Dokument eine DTD zugeordnet ist oder nicht. Bei gültigen Dokumenten muss die Referenzierung der Dokumenttyp-Deklaration nach der XML-Deklaration und vor dem ersten XML-Element folgen.

Das im Prolog enthaltene DOCTYPE-Tag verweist im Beispiel auf eine externe DTD. Dabei lassen sich optional lokale Deklarationen zwischen eckigen Klammern spezifizieren. Die Verarbeitung erfolgt in diesem Zusammenhang analog zur Verwendung von lokalen oder referenzierten Cascading Style Sheets - lokale Definitionen verarbeitet der Parser vor externen Definitionen.

Der Verweis auf eine externe Definition besteht aus dem Namen des Wurzelelements und dem Bezeichner SYSTEM mit einem System-Identifier, der eine externe Datei und deren URI angibt. Verweise auf eine externe Definition bestehen aus dem Namen für das Wurzel-Element und dem Bezeichner PUBLIC. Ein Beispiel für ein XML-Dokument samt Referenzierung einer externen und einer eingebetteten DTD:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE tecchannel PUBLIC "-//TECCHANNEL//DTD Artikel//DE"
"http://www.tecchannel.de/dtd/http://idgwptc.dev5.sr.nbsp.de/dtds/artikel.dtd" [
<!ENTITY ...>
<!NOTATION ...>
<!ELEMENT ...>
<!ATTLIST ...> ... ]>

Elementtyp-Deklaration

Über Elementtyp-Deklarationen bestimmt man die Elementstruktur eines Dokuments. Sie legen fest, ob ein Element leer beziehungsweise nicht leer ist. Falls es sich um ein nicht leeres Element handelt, bestimmen sie die möglichen Inhalte. Bei den Inhalten kann es sich um Elemente, Zeichendaten oder um einen Mix aus beiden handeln.

Eine typische Elementtyp-Deklaration sieht wie folgt aus:

<!ELEMENT gitarre (ibanez, reverend, esp)>

Oder allgemeiner:

<!ELEMENT elementname inhaltsspezifikation>

Elementname gibt den Elementnamen an. Inhaltsspezifikation beschreibt, welche Informationen im Inhaltsbereich eines Elements enthalten sein dürfen. Obige Beispieldeklaration identifiziert das Element mit der Bezeichnung gitarre, das die Inhalte ibanez, reverend und esp zulässt.

Damit Elemente mehrere Inhalte aufnehmen können, müssen über die Inhaltsspezifikationen bestimmte Vorgaben definiert werden. Optionale Operatoren definieren beispielsweise die Abfolge oder die Häufigkeit von Elementen. Die Funktion der Inhaltsspezifikation und der Operatoren zeigt folgendes Beispiel:

<!ELEMENT gitarre (ibanez+, reverend, esp?)>

Diese Elementtyp-Deklaration identifiziert das Element mit der Bezeichnung gitarre. Im Unterschied zu obigem Beispiel müssen aber ibanez und reverend enthalten sein, esp hingegen kann im Element enthalten sein, muss es aber nicht. Die Kommata zwischen den Elementnamen zeigen an, dass sie in exakt dieser Reihenfolge auftreten müssen. Das Pluszeichen bestimmt, dass der Elementname ibanez auch mehrfach auftreten kann. reverend muss exakt einmal auftreten.

Das komplette Beispiel, oben die zu Grunde liegende DTD, unten ein Beispiel für ein gültiges XML-Dokument:

<!ELEMENT gitarre (ibanez+, reverend, esp?)>
<!ELEMENT ibanez (#PCDATA)>
<!ELEMENT reverend (#PCDATA)>
<!ELEMENT esp (#PCDATA)>

<?xml version="1.0"?>
<!DOCTYPE gitarre SYSTEM "gitarre.dtd">
<gitarre>
<ibanez>rg550 silver sand</ibanez>
<ibanez>jem7dbk black</ibanez>
<reverend>commando</reverend>
</gitarre>

Ordnungsoperatoren

Nachstehende Übersicht fasst die verschiedenen Operatoren zusammen.

Übersicht Operatoren

Operator

Definition

, (Komma)

Definiert die strikte Abfolge von Elementen.

| (Balken)

Definiert alternative Elemente.

? (Fragezeichen)

Definiert optionale Elemente.

Häufigkeitsoperatoren

* (Stern)

Definiert beliebig häufiges Auftreten von Elementen, auch das Nichtauftreten.

+ (Plus)

Elemente müssen mindestens einmal auftreten.

Klammerung

( ... ) (Klammern)

Dient der Einbettung vom Elementen.

Zusätzlich lassen DTDs zwei weitere Inhaltsspezifikationen zu: Das Schlüsselwort EMPTY zeigt an, dass das Element keinen Inhalt und damit auch kein End-Tag aufweist. Das Schlüsselwort ANY zeigt an, dass jeder beliebige Inhalt erlaubt ist.

Attributlisten-Deklaration

Mit der Attributlisten-Deklaration bestimmt man, welche Attribute die einzelnen Elemente besitzen dürfen oder müssen. Außerdem definiert man, welche Werte diesen zugewiesen werden können. Sie besitzt folgende Form:

<!ATTLIST elementname attributliste>

Eine Attributliste besteht aus einer oder mehreren durch Leerraum getrennten Attribut-Deklarationen. Attributlisten haben folgende Form:

attributname attributtyp vorgabedeklaration

In der Anwendung zeigen sich die Attributlisten-Deklarationen in DTDs in dieser Form:

<!ATTLIST lieferung_an
name CDATA #IMPLIED
strasse CDATA #IMPLIED
stadt CDATA #IMPLIED
plz CDATA #IMPLIED
>

Hier ein einfaches XML-Dokument, das entsprechend obiger Beispiel-Attributdeklaration gültig ist:

<?xml version='1.0'?>
<!DOCTYPE lieferung_an SYSTEM "anschrift.dtd">

<lieferung_an name="Holger Reibold"
strasse="1, square des cerisiers"
stadt="Stiring-Wendel"
plz="57350">
</lieferung_an>

Attributtypen

Die verfügbaren Schlüsselwörter samt Beschreibung sind in den beiden nachstehenden Tabellen zusammengefasst.

Attributtypen

Schlüsselwort

Beschreibung

CDATA

Dem Attribut lässt sich jede beliebige Zeichenkette zuordnen.

NMTOKEN oder NMTOKENS

Dem Attribut muss ein Name zugeordnet werden, der den Namenskonventionen von XML folgt. Der Plural erlaubt die Verwendung von mehreren durch Leerraum getrennten Namen.

ID

Über IDs sind Elemente individuell identifiziert. Dabei müssen alle ID-Werte in einem Dokument unterschiedlich sein.

IDREF oder IDREFS

ID-Referenz, die auf Instanzen von Elementen verweist. Der Plural erlaubt die Verwendung von mehreren Referenzen.

NOTATION

Dem Attribut lässt sich über eine Notation-Deklaration ein definierter Notationtyp zuweisen.

ENTITY oder ENTITIES

Der Attributwert muss der Name einer Entität sein. Der Plural erlaubt die Verwendung von mehreren Entitäten, die durch Leerraum zu trennen sind.

(name_a|...|name_x)

Namensliste. Man bezeichnet diesen Typ auch als Aufzählungstyp. Als Wert lässt sich ihm einer der in der Deklaration durch Balken getrennt angegebenen Namen zuweisen.

Vorgabedeklaration

Deklaration

Beschreibung

#REQUIRED

Attributsabgabe erforderlich.

#IMPLIED

Optionales Attribut.

#FIXED "vorgabe"

Attribut besitzt festen Vorgabewert; dieser ist nicht veränderbar.

"vorgabe"

Weist dem Attribut immer den Vorgabewert zu, wenn das XML-Dokument keinen Wert vorgibt.

Entitäten-Deklarationen

Über Entity-Deklarationen lassen sich neue Entitäten definieren. Entitäten kann man als eine Zuordnung von Namen zu einer Ersetzung verstehen. Taucht der Bezeichner im XML-Dokument auf, wird die Ersetzung vom Parser vorgenommen. Dieses Konstrukt kann für Textblöcke, DTDs oder auch Referenzen zu externen Dateien verwendet werden, die entweder Text oder Binärinformationen enthalten. Man unterschiedet dabei zwischen internen, externen und Parameter-Entities.

Bei internen Entitäten steht die Ersetzung direkt in der Deklaration. Da interne Entitäten vom XML-Prozessor analysiert werden, muss der Inhalt XML-konform sein. Man bezeichnet den Inhalt interner Entities auch als Ersetzungstext. Bei externen Entities unterschiedet man zudem zwischen analysierten und nichtanalysierten Entities. Grundsätzlich liegt der Inhalt bei externen Entities in einer separaten Speicherungseinheit.

Analysierte externe Entitäten enthalten wie interne Entitäten XML-konforme Inhalte und werden ebenfalls analysiert. Ihr Inhalt besteht meist aus XML-Teildokumenten. Nichtanalysierte externe Entities können dagegen beliebigen Inhalte wie Bilder, Töne oder Videos enthalten. Entitäten-Deklarationen weisen folgendes Format auf.

<!ENTITY referenzname ersetzung>

Handelt es sich um interne Entitäten, folgen der Name und der Wert. Bei der Deklaration externer Entitäten folgt dem Namen entweder das Literal SYSTEM und ein System-Identifier oder das Literal PUBLIC und ein Public-Identifier mit optionalem System-Identifier.

Parameter-Entities unterscheiden sich von externen Entities durch ein eingeschlossenes Prozentzeichen (%) zwischen der Einleitung und dem Entity-Namen. Parameter-Entities haben gegenüber allgemeinen Entities die Besonderheit, dass sie nur in DTDs verwendet werden können. Beim Parsen werden sie innerhalb der DTD durch den Ersetzungstext ausgetauscht.

Notations-Deklaration

Bei der Verwendung nichtanalysierter externer Entities oder Elementen mit einem Notationsattribut ist das Datenformat meist nicht XML-konform. Eine Notation identifiziert in diesen Fällen das Format durch einen Bezeichner. Der Bezeichnername wird über eine Notation-Deklaration definiert.

Eine solche Deklaration gibt außerdem einen externen Identifier an. Dieser ermöglicht dem XML-Prozessor, ein Hilfsprogramm zu starten, das die Daten in der gegebenen Notation verarbeitet.

Mit der Notation-Deklaration kann also ein neuer Datentyp deklariert und mit einem externen Programm verknüpft werden. Eine Beispielnotation, die den Dateityp jpeg mit einem externen Programm verknüpft, sieht so aus:

<!NOTAION jpeg SYSTEM "jpegviewer.exe">

Die DTD-Nachfolger: XML-Schemata

DTDs definieren die gültige Reihenfolge und die Verschachtelung von Elementen. Dennoch unterliegen sie zum Teil erheblichen Einschränkungen. So verwenden sie ein Nicht-XML-Format und unterstützen keine Namensräume . In der Verwendung von Datentypen ist man sehr begrenzt.

Solche Einschränkungen lösen XML-Schemata. Schemata verwenden wie XML-Dokumente eine XML-Syntax. Zudem unterstützen sie eine breite Palette an Datentypen, auch Boolsche-, Integer- beziehungsweise Dezimalwerte.

Für mehr Flexibilität sorgt der Einsatz benutzerdefinierter Datentypen - die Schema-Spezifikation bezeichnet sie auch als Archetypen. Mit Archetypen ist es beispielsweise denkbar, dass man den Datentyp Postanschrift mit den beiden Elementen Lieferadresse und Rechnungsadresse definiert.

Ebenso lassen sich Attribute gruppieren. Dies ermöglicht, allgemeine Attribute allen Elementen und definierte Attribute nur bestimmten Elementen zuzuweisen.

Über das Content-Model beschreibt ein Schema die Reihenfolge von Elementen, und über Datentypen legt es die gültigen Dateneinheiten fest. Ein Schema kann beispielsweise vorgeben, dass Adressen aus den Elementen Name, Straße, Stadt, Postleitzahl und Land bestehen - und zwar in exakt dieser Reihenfolge. Darüber hinaus lässt sich festlegen, dass das Element Postleitzahl einen fünfstelligen Zahlenwerten enthalten muss und keinen Text enthalten darf.

Schema-Beispiel

XML-Schemata führen eine Art Vererbung ein, wie man sie von objektorientierten Programmiersprachen kennt. Zusätzlich ist die Namespace-Unterstützung in der Spezifikation definiert. Inzwischen gibt es eine ganze Reihe von XML-Werkzeugen, die die Entwicklung von XML-Schemata vereinfachen.

Mit entsprechenden XML-Werkzeugen lassen sich Schemata erzeugen. Hier ein Beispiel, wie XML-Dokumente und die zugehörige Schema-Definition in der Praxis aussehen können. Das vorliegende Beispiel beschreibt die Auslieferung zweier CDs an einen Kunden. Das XML-Dokument:

<?xml version="1.0"?>
<auslieferung>
<ausliefern_an>
<name>Holger Reibold</name>
<strasse>1, Square des cerisiers</strasse>
<stadt>57350 Stiring-Wendel</stadt>
<land>Frankreich</land>
</ausliefern_an>
<waren>
<cd>
<titel>SelfNaked</titel>
<menge>1</menge>
<preis>29,99</preis>
</cd>
<cd>
<titel>Covenant</titel>
<menge>1</menge>
<preis>19.90</preis>
</cd>
</waren>
</auslieferung>

Das zugehörige XML-Schema:

<xsd:schema xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<xsd:element name="auslieferung" type="bestellung"/>

<xsd:complexType name="bestellung">
<xsd:element name="ausliefern_an" type="lieferadresse"/>
<xsd:element name="waren" type="cds"/>
</xsd:complexType>

<xsd:complexType name="lieferadresse">
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="strasse" type="xsd:string"/>
<xsd:element name="stadt" type="xsd:string"/>
<xsd:element name="land" type="xsd:string"/>
</xsd:complexType>

<xsd:complexType name="cds">
<xsd:element name="cd" type="cdware"/>
</xsd:complexType>

<xsd:complexType name="cdware">
<xsd:element name="titel" type="xsd:string"/>
<xsd:element name="menge"
type="xsd:positiveInteger"/>
<xsd:element name="preis" type="xsd:decimal"/>
</xsd:complexType>

</xsd:schema>

Fazit

Momentan spielen DTDs in der XML-Entwicklung die Hauptrolle. Mittelfristig werden sie von der Schemata-Technologie abgelöst. Das zeigt beispielsweise die Entwicklung aktueller XML-Editoren, die nach und nach um visuelle Schemata-Funktionen erweitert werden. Neben dem vom W3-Konsortium definierten Schema-Mechanismus hat Microsoft inzwischen eine eigene Lösung entwickelt. Während XML-Schema eine plattformneutrale Sprache ist, handelt es sich bei Microsofts Schema-Entwurf um eine Windows-spezifische Entwicklung.

Weitere Informationen zu Dokumententypdefinitionen und Schemata finden sie insbesondere bei DTD.com oder bei Schema.net. (sda)