Komplexe DTD'sEine DTD ist schnell geschrieben, doch wie sieht eine große DTD aus, welche auf das komplexe DTD Vokabular zurückgreift?

In einer DTD sind die Definitionen der verwendeten Elemente in einem XML Dokument. Das bedeutet, das die DTD dem Element die spezifischen Eigenschaften gibt. Die DTD bestimmt, ob ein Element Attribute besitzt, wenn ja, dann welche. Sie definiert die Eigenschaften der Attribute, und gibt an welche Werte das Element oder die Attribute annehmen kann.

Es gibt interne und externe DTDs. Interne DTDs sind in dem Dokument selbst definiert, die Definitionen werden nur auf das Dokument angewendet. Externe DTDs befinden sich in ausgelagerten Dateien. Diese Dateien haben die Dateiendung *.dtd. Eine externe DTD muss in das jeweilige XML-Dokument eingebunden werden.

Das erste Beispiel ist ein einfaches XML Dokument, mit einer genauso einfachen DTD.

versuch1.xml:


<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE name SYSTEM "name.dtd">

<name>Thiemo</name>

name.dtd:

<!ELEMENT name (#PCDATA)>


Das Ergebnis ist ein gültiges und wohlgeformtes XML-Dokument:

Ein gültiges, wohlgeformtes XML Dokument
Ein gültiges, wohlgeformtes XML Dokument

Die DTD wird über den Befehl <!DOCTYPE name SYSTEM "name.dtd"> in das Dokument eingebunden. Dieser Befehl hat das Attribut SYSTEM, nach welchem die Adresse zur DTD angegeben wird.

Die DTD ist nicht sonderlich interessant. Es wird das Element name definiert.
Das Schema einer Elementdefinition ist immer gleich:

<!ELEMENT Name (Inhalt)>

Als Inhalt wurde hier #PCDATA festgelegt. Dies besagt, das jeder Inhalt möglich ist. Jedoch ist die Verwendung eines anderen Elementes innerhalb dieses Elementes strengstens untersagt.

<name><fett>Thiemo</fett></name>


Dieser Code ist mit der DTD ungültig, da nicht definiert wurde, dass das Element <fett> innerhalb des Elementes <name> verwendet wird.

Eine Komplexere DTD ist die zur Adressenverwaltung. Man möchte ein XML Dokument als Adressendatenenbank verwenden. Hierbei soll die XML Struktur wie folgt aussehen:

adressen.xml
:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE adressen SYSTEM "adressen.dtd">

<adressen_db>

<adresse>
<anrede>Herr</anrede>
<name>Thiemo Fetzer</name>
<strasse>Bilharzstrasse 1</strasse>
<plz>89081</plz>
<ort>Ulm</ort>
</adresse>

<adresse>
<name>Uni Ulm</name>
<postfach>7561</postfach>
<plz>89077</plz>
<ort>Ulm</ort>
</adresse>

</adressen_db>

Schon bevor man sich mit der DTD beschäftig muss man einige Grundvorraussetzungen festlegen. Die Datei beeinhaltet zwei Datensätze, die jeweils eine verschiedene Adresse beinhaltet. Man muss in der DTD also definieren, das das Element adresse mehr als einmal im Dokument auftreten kann.
Zudem befinden sich in der Datenbank Anschriften von Gebäuden, und von Personen. Bei der Anschrift an eine Person ist eine Anrede vorhanden, bei einer Gebäudeanschrift würde diese keinen Sinn machen. Deshalb muss das Unterelement andrede als optional definiert werden. Auch dies ist über die DTD möglich.
Eine weitere Besonderheit die auffällt ist, das im ersten Datensatz die Strasse und Hausnummer angegeben ist, im zweiten Datensatz nur das Postfach. Hierbei muss es möglich sein, entweder das Element strasse festzulegen, oder ein postfach zu definieren. Dies wird ebenfalls mit der DTD erreicht.

adressen.dtd:

<!ELEMENT adressen_db (adresse)*>

<!ELEMENT adresse (anrede?, name, (postfach | strasse), plz, ort)>

<!ELEMENT anrede (#PCDATA)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT postfach (#PCDATA)>
<!ELEMENT strasse (#PCDATA)>
<!ELEMENT plz (#PCDATA)>
<!ELEMENT ort (#PCDATA)>

Die erste Eigenschaft der DTD, die wir ermittelt haben, ist, dass das Element adresse mehrmals vorkommen kann. Dies wird durch das * bei der Definition des Wurzelelementes adressen_db erreicht.

<!ELEMENT adressen_db (adresse)*>

Diesem Wurzelelement wird das Unterelement adresse zugewiesen, welches durch das * die Eigenschaft hat mehrmals vorzukommen, es kann aber auch leer sein.

Danach wird das Unterelement adresse genauer definiert.

<!ELEMENT adresse (anrede?, name, (postfach | strasse), plz, ort)>

Wir hatten festgestellt, das in dem Dokument die Anrede als optional gelten soll. Dies wird durch das anrede? erreicht. Es besagt, das das Element vorkommen kann, aber nicht zwingend definiert werden muss.
Den nächsten Zustand der ermittelt wurde war, das entweder ein Postfach, oder eine Strasse angegeben wird. Dies wird durch (postfach | strasse) erreicht. Der | dient hier als Operator, welcher das "oder" ausdrückt. Eines dieser Elemente muss jedoch definiert sein.
Die Elemente name, plz und ort sind "normale" Elemente, die gesetzt werden müssen. Die genauere Definition der einzelnen Unterelemente erfolgt darunter.

Wie Sie an diesem Beispiel gesehen haben gibt es viele Möglichkeiten eine DTD zu verfeinern, und die Inhalte abzustimmen.

Ein Problem ist jedoch immer noch vorhanden. Was ist, wenn man über ein Skript z.B. einen Datensatz ermitteln will?
Das Problem liegt einzig und allein darin, das die Datensätze nicht genauer Definiert sind. Sie sind nicht einmalig. Diese Eigenschaft wurde durch

<!ELEMENT adressen_db (adresse)*>

erreicht. Es besagt, dass das Element adresse mehrmals vorkommen darf. wir müssen jetzt dem Element adresse ein Attribut geben, welches es eindeutig bezeichnet, gewissermaßen eine ID.
Die Struktur des XML-Dokumentes sähe dann wie folgt aus:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE adressen SYSTEM "adressen.dtd">

<adressen_db>

<adresse nr="1">
<anrede>Herr</anrede>
<name>Thiemo Fetzer</name>
<strasse>Bilharzstrasse 1</strasse>
<plz>89081</plz>
<ort>Ulm</ort>
</adresse>

<adresse nr="2">
<name>Uni Ulm</name>
<postfach>7561</postfach>
<plz>89077</plz>
<ort>Ulm</ort>
</adresse>

</adressen_db>

Wie Sie sehen wurde ein eindeutiger Bezeichner nr="" für jeden Datensatz eingeführt. Jeder Datensatz ist also einmalig. Daraus kann man jetzt schon schließen, das die DTD auf eine Wiederholungsanweisung für das Element adresse durch den * verzichten kann, da jedes Element einmalig bezeichnet ist.

adressen.dtd

<!ELEMENT adressen_db (adresse)>

<!ELEMENT adresse (anrede?, name, (postfach | strasse), plz, ort)>

<!ATTLIST adresse
nr CDATA #REQUIRED
>

<!ELEMENT anrede (#PCDATA)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT postfach (#PCDATA)>
<!ELEMENT strasse (#PCDATA)>
<!ELEMENT plz (#PCDATA)>
<!ELEMENT ort (#PCDATA)>

Die DTD ist geringfügig verändert worden. Eine Zeile wurde hinzugefügt.

<!ATTLISTadresse
nr
CDATA #REQUIRED
>


Diese Zeile definiert die Attribute für das Attribut adresse.
Das Schema dieser Definition ist immer gleich:

<!ATTLIST Elementname Attributname Inhalt [#REQUIRED|#IMPLIED|#FIXED "Fester Wert "|"Defaultwert"]>


Es können beliebig viele Attribute gesetzt werden. Jedes Attribut muss in einer eigenen Zeile definiert werden. In unserem Beispiel wurde als Inhalt CDATA definiert. Dieser Bezeichner gibt an, das der Inhalt des Attributes aus Zeichendaten besteht.
Die Bezeichner #REQUIRED, #IMPLIED, #FIXED geben die Eigenschaften des Inhaltes genauer an.
Der Bezeichner #REQUIRED gibt an, das dieses Attribut gesetzt werden muss. Der Bezeichner #IMPLIED gibt an, das die Setzung des Attributes optional ist (es muss nicht gesetzt werden).
Bei der Angabe #FIXED "Fester Wert" wird dem Attribut ein fester Wert gegeben. Das Attribut muss nicht mehr gesetzt werden, es wird automatisch gesetzt, mit dem Wert, der hinter #FIXED angegeben ist.
Ein sogenannter Defaultwert gilt für alle Attribute. Ist es nicht gesetzt, dann nimmt es diesen Wert an.
Man kann den Attributen auch direkt einen festen Wert geben, oder eine reihe von Werten bestimmen, welche verwendet werden dürfen.

websites.xml


<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE websites SYSTEM "websites.dtd">
<websites>

<website nr="1" punkte="5">
<name>devmag.net</name>
<url>http://www.devmag.net</url>
</website>


<website nr="2" punkte="4">
<name>XML-Magazin</name>
<url>http://www.xml-magazin.de</url>
</website>

</websites>

Die Datensätze haben ein weiteres Attribut erhalten. Das punkte Attribut gibt an, wieviele Punkte die Seite hat. Die maximale Punktzahl ist 5, die minimale Punktzahl ist 1. Damit das Dokument gültig ist kann nur aus diesen fünf Werten ausgewählt werden.

<!ELEMENT websites (website)>

<!ELEMENT website (name, url)>

<!ATTLIST adresse

nr CDATA #REQUIRED
punkte (1|2|3|4|5) #REQUIRED

>

<!ELEMENT name (#PCDATA)>
<!ELEMENT url (#PCDATA)>

Der Schlüssel liegt in der Definition des Attributes punkte.

punkte (1|2|3|4|5) #REQUIRED

In der Klammer werden die möglichen Werte angegeben. Diese sind mit einem | voneinander getrennt. Einer dieser Werte muss jedoch ausgewählt sein. Das verlangt die Eigenschaft #REQUIRED.

Diese Einführung in DTDs ist sehr komplex. Die Arbeit mit DTDs ist am Anfang sehr schwer zu verstehen, jedoch zeigen sich schnell die Möglichkeiten, und die Einfachheit der DTDs lässt sich auch schnell entdecken.

Bookmark setzen... These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Bloglines
  • MisterWong
  • MySpace
  • Reddit
  • SEOigg
  • Technorati
  • TwitThis
  • Y!GG
  • Google Bookmarks

Weiterführende Links: