Zu einer gültigen XML-Datei gehört stets eine Definition der verwendeten Tags. Wir zeigen, wie solch eine “Document Type Definition” (DTD) entsteht.
Im LinuxUser 11/2001 haben wir das Programm KXMLEditor vorgestellt und gezeigt, wie damit XML-Dateien erstellt werden. Gültige XML-Dokumente kann dieser XML-Editor jedoch nicht schreiben, da es keine Möglichkeit gibt, eine DTD, eine Document Type Definition, aufzusetzen, in der die verwendeten Tags festgelegt werden. Diese Lücke gilt es nun, mit einfachen Mitteln zu schließen.
DTD – wozu?
In XML sind Inhalt, Struktur und Layout der Daten strikt voneinander getrennt. Eine DTD definiert die Tags, die in einem Dokument Verwendung finden dürfen, beschreibt, wie diese Elemente ineinander geschachtelt werden können und legt schließlich die Attribute der einzelnen Tags fest [1]. Zum Erstellen dieser Definitionen benötigen Sie nichts weiter als einen beliebigen Editor, der Text unformatiert speichert, z. B. Kate oder (X)Emacs.
Mit Hilfe einer DTD kann ein XML-Parser feststellen, ob das XML-Dokument gültig ist, sich also an die in der DTD aufgestellten Regeln hält. Autoren von XML-Dokumenten schätzen DTDs, da sie darin auf einen Blick sehen, welche Tags auf welche Art verwendet werden.
Intern und extern
Es gibt zwei Möglichkeiten, eine DTD mit einem XML-Dokument zu verbinden: Interne DTDs stehen im Prolog, dem Dateikopf der XML-Datei, gleich hinter der <?xml>-Zeile:
<?xml version="1.0">
<!DOCTYPE Name_der_Definition [[Hier folgt die DTD…]
]>[… und hier stehen die Text-Daten]
Externe DTDs befinden sich in einer separaten Datei, auf die das XML-Dokument verweist. Dieser Eintrag steht ebenfalls im Prolog und sieht für eine in der Datei adressen.dtd enthaltene DTD namens adressen, die im selben Verzeichnis wie das XML-Dokument liegt, so aus:
<?xml version="1.0"> <!DOCTYPE adressen SYSTEM "adressen.dtd">[…]
Das Schlüsselwort SYSTEM besagt, dass es sich um eine private DTD handelt, die nicht öffentlich zugänglich ist. Mit PUBLIC werden hingegen “öffentliche” DTDs gekennzeichnet, die z. B. auf einem Web-Server liegen. So ist etwa die DTD für HTML 4.0 (XHTML) öffentlich und wird folgendermaßen in ein HTML-Dokument eingebunden:
<!doctype html public "-//W3C//DTD HTML 4.0 //EN">
Sie können eine beliebige URL als DTD-Quelle eingeben und dabei relative und absolute Pfade verwenden.
Externe DTDs sind genauso aufgebaut wie interne, allerdings fehlt ihnen das Schlüsselwort <!DOCTYPE>, da es schon in der XML-Datei steht. Ihr Vorteil: Sie können von mehreren Dateien verwendet werden und sind leichter zu warten. Zudem sorgen sie dafür, dass Daten und Definition des XML-Dokuments sauber getrennt bleiben.
Aufbau einer DTD
Eine DTD sieht allgemein so aus:
<!ELEMENT Name_der_Definition (Typ_des_Wurzel-Elements)> <!ELEMENT Name_des_Elements (Typ_des_Elements)>[…]
Die Definition eines Tags beginnt mit dem XML-Befehl <!ELEMENT, es folgt sein Name und in runden Klammern, welcher Art das Element ist. Besitzt es Unterelemente, stehen diese innerhalb der Klammer; ansonsten gibt man seinen Typ an: #PCDATA oder #CDATA. #PCDATA überprüft der Parser darauf, ob an dieser Stelle im XML-File eingegebene Daten den definierten Regeln entsprechen; bei Daten vom Typ #CDATA unterbleibt ein solcher Check.
Für die Namen von Definitionen und Tags dürfen Sie keine deutschen Umlaute und keines der in Kasten 1 aufgezählten Sonderzeichen verwenden.
Kasten 1: In Definitionen nicht erlaubt
Ä ä Ö ö Ü ü ß * + ! ” § $ % & / ( ) = ? \ ~ # , . ; : ^ ° @ < > |
Elemente einer XML-Datei werden in einer Baumstruktur ineinander verschachtelt. So verwundert es nicht, dass es sich beim ersten in einer DTD definierten Element um das Root-(Wurzel-)Element des Dokuments handelt. Die DTD muss denselben Namen tragen wie das Root-Element; achten Sie daher besonders auf Groß- und Kleinschreibung: <ADRESSE> und <adresse> sind in XML zwei verschiedene Elemente. Da das Root-Element der Ursprung des Dokuments ist, darf es nur eines davon geben, alle anderen Elemente müssen sich vom Root-Element ableiten. Folgende DTD ist beispielsweise falsch, da ein Wurzel-Element fehlt:
<!DOCTYPE adressen [
<!ELEMENT datensatz(#PCDATA)>
<!ELEMENT info(#PCDATA)>
]>
Definition einer Adressdatenbank
Am praktischen Beispiel lernt es sich besser, weshalb wir im Folgenden eine DTD für die in Heft 11/2001 vorgestellte XML-Adressdatenbank entwickeln. Ihren Aufbau zeigt Abbildung 1.
<adressen> fungiert als Root-Element der Datenbank, weshalb auch die DTD den Namen adressen bekommt und als interne DTD wie folgt beginnt:
<!DOCTYPE adressen [[…]
]>
Unterhalb des Wurzel-Elements soll es beliebig viele Elemente <datensatz> geben. Jeder Datensatz wiederum enthält die Elemente <vorname>, <nachname>, <strasse>, <plz>, <ort> und <tel>. Die DTD drückt diese Abhängigkeit so aus, dass die Namen der untergeordneten Elemente in Klammern hinter den Namen der übergeordneten stehen. Auf die Vorgaben für das Wurzel-Element folgen die übrigen Elementdefinitionen (Listing 1). Durch die Einrückungen im Quelltext wird die Struktur der XML-Datei darin schon sehr schön sichtbar.
Listing 1
DTD für eine XML-Adressdatenbank
<!ELEMENT adressen(datensatz)>
<!ELEMENT datensatz(vorname,nachname,strasse,plz,ort,tel)+>
<!ELEMENT vorname(#PCDATA)?>
<!ELEMENT nachname(#PCDATA)>
<!ELEMENT strasse(#PCDATA)>
<!ELEMENT plz(#PCDATA)>
<!ELEMENT ort(#PCDATA)>
<!ELEMENT tel(#PCDATA)>
Für die Verwendung der Tags können Sie Regeln festlegen. Ein Pluszeichen vor der schließenden spitzen Klammer der Elementdefinition (wie im Beispiel bei <datensatz>) besagt, dass es beliebig viele, mindestens aber ein Element dieses Typs geben muss. Das Sternchen bedeutet, dass ein XML-Dokument beliebig viele Elemente dieser Art (auch keines) an der jeweiligen Stelle enthalten darf. Ein Fragezeichen wie beim Element <vorname> markiert ein optionales Element.
Attribute
Bislang haben wir in der DTD die Verwendung der Tags beschrieben. Manchmal will man ihnen jedoch noch weitere Eigenschaften mitgeben, im Beispiel etwa, ob es sich um eine private oder geschäftliche Telefonnummer handelt. Diese Zusätze heißen Attribute. Sie werden im Anschluss an das Element, für das sie gelten, definiert:
<!ATTLIST Tagname Attributname(Attributwert) Option>
Um für das Tag <tel> ein Attribut art mit den Werten privat und geschaeft zu definieren, schreiben Sie hinter seine Definition als letzte Zeile von Listing 1:
<!ATTLIST tel art (privat|geschaeft) #REQUIRED>
Das Schlüsselwort #REQUIRED besagt, dass der Autor eines die DTD verwendenden XML-Dokuments ungültiges XML erzeugt, wenn er das Attribut nicht mit angibt. Ein optionales Attribut wird stattdessen mit #IMPLIED markiert. Attribute müssen in der XML-Datei stets in doppelten Anführungszeichen stehen. Einen vollständigen Datensatz aus der XML-Datenbank entnehmen Sie Listing 2.
Listing 2
Ein Beispieldatensatz
<adressen>
<datensatz>
<nachname>Hansen</nachname>
<vorname>Karl</vorname>
<strasse>Fischergasse 12</strasse>
<plz>12345</plz>
<ort>Seeheim</ort>
<tel art="privat">0123-12 34 56</ort>
</datensatz>[…]
</adressen>
Mit diesem Wissen können Sie bereits einfache DTDs erstellen. Doch es wäre zu schön, um wahr zu sein, wenn es zu diesem Thema nicht noch mehr zu sagen gäbe: In [2] finden Sie ausführliche Informationen, unter [3] einen Crashkurs in Sachen XML und DTD.
Auch im LinuxUser bekommen Sie weiteres Rüstzeug: Nachdem Inhalt und Struktur der XML-Datenbank feststehen, zeigt Heft 01/2002, wie XML-Dateien mit Hilfe von XSLT, “EXtensible Stylesheet Language Transformation”, für die Ausgabe auf dem Bildschirm und dem Drucker formatiert werden. Dann werfen wir auch einen kurzen Blick auf die Dokumentation des KDE-Projekts, die vollständig in XML erstellt wird.
Glossar
-
XML
-
“EXtensible Markup Language”. Eine auf SGML basierende Auszeichnungssprache mit der Möglichkeit, eigene Tags zu definieren.
-
Ein Befehl in XML.
-
XML-Parser
-
Ein XML-Parser ist ein Programm, das XML-Dateien einlesen und auf Richtigkeit prüfen kann. Jeder XML darstellende Browser enthält einen solchen Parser.
-
URL
-
“Uniform Resource Locator”, die eindeutige Adressenangabe für eine Datei im Internet.
-
Pfade
-
Der “Weg” zu einer Datei auf einem lokalen Dateisystem, also die Angabe aller Verzeichnisse, über die man “gehen” muss, um zu ihr zu gelangen, wird als Pfad bezeichnet.
Infos
[1] http://xml.cnec.org/basics/index.php
[2] Michael Seeboerger-Weichselbaum: “XML. Das Einsteigerseminar”, 3. Auflage Kaarst 2001
[3] http://www.geocities.com/SiliconValley/Peaks/5957/10minxml.html





