Die DTD
In der Document Type Definition (DTD) können die im Dokument zulässigen Elementtypen mit ihren Inhaltsmodellen und Attributen definiert werden. Eine DTD ist somit eine schematische Beschreibung des XML-Dokumentes, die allerdings optional ist. Ein Schema für ein Dokument kann auch mit einer anderen Schemasprache, beispielsweise XML Schema, beschrieben sein. Ist keine Validierung notwendig, so ist es auch erlaubt, überhaupt keine schematische Beschreibung zu haben.
Wenn eine DTD vorhanden ist, wird sie durch <!DOCTYPE eingeleitet. Es folgen der Name des Dokumenttyps und, von eckigen Klammern umschlossen, Elementtyp- und Attributtypdefinitionen.
<!DOCTYPE Klinik [ ... ]>
Für jeden Elementtyp werden, durch <!ELEMENT eingeleitet, der Name und das Inhaltsmodell definiert. Als Auswahl für das Inhaltsmodell stehen neben dem leeren Inhalt eine Kombination aus Kindelementen oder ein textueller Inhalt oder eine Mischung daraus zur Verfügung. In diesen Fällen ist das Inhaltsmodell von runden Klammern umschlossen. Ein rein textueller Inhalt wird durch (#PCDATA) spezifiziert. Dabei ist eine nähere Typangabe (beispielsweise numerische Daten) nicht möglich:
<!ELEMENT Name (#PCDATA)>
Ein leeres Element wird durch das Inhaltsmodell EMPTY in der Typdefinition gekennzeichnet. Elemente können wiederum Elemente enthalten (komplexer Elementinhalt). In diesem Fall kann man die erlaubten Elemente und Bedingungen an deren Kombination spezifizieren. Wenn mehrere Subelemente in einer bestimmten Reihenfolge auftreten sollen, werden diese durch ein Komma getrennt ("sequence"). Eine Auswahl ("choice") aus mehreren möglichen Elementen wird durch einen senkrechten Strich spezifiziert.
<!ELEMENT Bett EMPTY>
<!ELEMENT Klinik (Name, Stationen)>
<!ELEMENT Adresse (Stadt, (Strasse | Postfach))>
Das erste Beispiel zeigt die Definition eines leeren Elementes, das zweite Beispiel die Definition eines Elementtyps Klinik, wobei ein Element dieses Typs als Kinder je ein Element Name und Stationen in dieser Reihenfolge enthalten muss, und das dritte Beispiel die Definition eines Elementtyps Adresse, bei dem Elemente zunächst ein Kindelement Stadt, und dann entweder ein Element Strasse oder ein Element Postfach enthalten müssen.
Wird nichts explizit spezifiziert, ist die Häufigkeit auf genau 1 beschränkt, d.h., ein entsprechendes Element muss genau einmal in einem Element des beschriebenen Typs vorkommen. Ein "?" kennzeichnet, dass ein solches Element höchstens einmal auftritt (also optional ist), ein "+" bedeutet, dass ein Element mindestens einmal erscheint, und ein "*" bedeutet, dass ein Element beliebig oft vorkommen (gegebenenfalls auch ganz fehlen) kann. Im folgenden Beispiel muss mindestens ein Vorname auftreten, während eine beliebige Anzahl von Telefonnummern und Faxnummern in beliebiger Reihenfolge erlaubt ist:
<!ELEMENT Person (Name, Vorname+, (Telefon | Fax)*)>
Gemischter Inhalt wird dadurch beschrieben, dass an #PCDATA alle erlaubten Elementtypen mit einem senkrechten Strich angeschlossen werden. Eine Einschränkung der Kardinalität ist dabei nicht möglich – als Kardinalität des Inhaltsmodells muss "*" angegeben werden:
<!ELEMENT Befund (#PCDATA | b)*>
In manchen Fällen, so beispielsweise bei XHTML, können Elemente fast aller definierten Elementtypen als Inhalt eines Elementes vorkommen. Für eine kompakte Notation in diesem Fall wurde das Schlüsselwort ANY eingeführt. Es erlaubt alle in der DTD spezifizierten Elementtypen.
Schließlich können in der DTD auch die für ein Element zulässigen Attribute beschrieben werden. Während Elementnamen im ganzen Dokument eindeutig sein müssen, müssen Attributnamen nur innerhalb ihres Elementes eindeutig sein. Daher werden sie unter Angabe des zugehörigen Elementtyps definiert (als ATTLIST). Eine Attributliste kann mehrere Attributtypen für einen zugehörigen Elementtyp definieren – es kann aber zu einem Elementtyp auch mehrere Attributlisten geben. Das allgemeine Format lautet:
AttlistDecl ::= <!ATTLIST Name AttDef*>
AttDef ::= Name AttType DefaultDecl
DefaultDecl ::= #REQUIRED | #IMPLIED | #FIXED AttValue | AttValue
Ein Beispiel für eine solche Attributdeklaration ist:
<!ATTLIST Station Leitung CDATA #REQUIRED>
Folgende Attributtypen kann man in einer DTD verwenden:
- Zeichenkette (String)
Die Zeichenkette wird als CDATA bezeichnet. - Identifikatortyp ID
Die Werte aller ID-Attribute müssen im Dokument eindeutig sein (auch wenn es sich um verschiedene Attribute handelt) und unterliegen syntaktischen Beschränkungen. - Referenztyp auf Attribute des Typs ID
Je nachdem, ob es sich um eine einzelne Referenz oder eine Liste solcher Referenzen handelt, heißt der Typ IDREF oder IDREFS. - Einzelnes Token (NMTOKEN) bzw. Liste von Tokens (NMTOKENS)
Ein einzelnes Token ("name token") besteht aus einer Folge von Buchstaben, Zahlen und bestimmten Sonderzeichen, aber ohne Leerzeichen. - Aufzählungstypen
Die einzelne Werte sind dabei durch einen senkrechten Strich getrennt.
Außerdem gibt es in der Attributdefinition noch Angaben zu Häufigkeit und Vorbelegungswerten ("default values").
- #REQUIRED
Das Attribut muss explizit im Element vorkommen. - #IMPLIED
Das Attribut darf fehlen und hat dann keinen Vorbelegungswert. - Angabe eines Vorbelegungswertes
Dieser Wert gilt, wenn das Attribut in einem Element nicht explizit einen anderen Wert trägt. - #FIXED
Zusammen mit Angabe eines Wertes bedeutet dies einen Fehler, wenn das Attribut im Dokument mit einem anderen Wert auftritt. Der angegebene Wert gilt in jedem Fall.
Attributwerte werden bei der Verarbeitung durch einen XML-Prozessor einer Normalisierung unterzogen. Dazu gehört neben dem Auflösen von Zeichen- und Entity-Referenzen, die im Folgenden ausführlich beschrieben werden, auch die Umwandlung von Leerraum ("whitespace"): Alle Leerraumzeichen (U+0009, U+000A, U+000D) werden zunächst zu Leerzeichen (U+0020) umgewandelt.
Die Reihenfolge der Definitionen in der DTD spielt keine Rolle. Sie kann ohne Änderung der Semantik vertauscht werden. Alle Definitionen in der DTD sind global. Das bedeutet, dass alle Elementtypdefinitionen auf alle anderen definierten Elementtypen (und sich selbst) in der Inhaltsdefinition Bezug nehmen können. Es können somit für einen Elementtyp mehrere "Elterntypen" definiert werden. Außerdem wird so auf Typebene eine direkte oder indirekte Rekursion möglich, wie hier am Beispiel einer Definition für einen Baum gezeigt wird:
<!ELEMENT Knoten (Knoten*)>
<!ATTLIST Knoten Name CDATA #REQUIRED>
Umgekehrt bedeutet die Globalität der Definitionen auch, dass Elementtypen, die in verschiedenen Kontexten verwendet werden, kein kontextspezifisches Inhaltsmodell haben können. Dies ist nur möglich, wenn der Elementtyp anders benannt wird. Wie man sieht, sind die Typspezifikationen für Attribute und noch mehr die für Elemente recht unspezifisch. Mit XML Schema existieren viel ausgefeiltere Möglichkeiten der Typdefinition.
Eine DTD kann auch extern zum Dokument vorliegen. In diesem Fall enthält das Dokument nur eine Referenz, zum Beispiel:
<!DOCTYPE Klinik SYSTEM "http://www.xquery-buch.de/klinik.dtd">
Des Weiteren ist auch die Kombination aus interner und externer DTD möglich. In diesem Fall überschreiben die Definitionen der internen DTD die der externen DTD. Als Konsequenz können Dokumente, die alle auf dieselbe externe DTD verweisen, trotzdem unterschiedliche Typdefinitionen haben. Einige der eingeführten Konzepte zeigt das erweiterte Beispieldokument:
<?xml version="1.0"?>
<!DOCTYPE Klinik [
<!ELEMENT Klinik (Name, Stationen)>
<!ELEMENT Name (#PCDATA)>
<!ELEMENT Stationen (Station*)>
<!ELEMENT Station (Name, Standort)>
<!ATTLIST Station Leitung CDATA #REQUIRED>
]>
<!-- Dokument erstellt am 1.1.2004 -->
<?xml:stylesheet type="text/xsl" href="stylesheets/print.xsl" ?>
<Klinik>
<Name>Hochwaldklinik</Name>
<Stationen>
<Station Leitung="Pfleger_01">
<Name>Notaufnahme</Name>
<Standort>Vorort</Standort>
</Station>
</Stationen>
</Klinik>
Quelle: "XQuery – Grundlagen und fortgeschrittene Methoden", dpunkt-Verlag, Heidelberg (2004)
<< zurück | vor >> |