Attribut-Deklarationen

(Auszug aus "XML in a Nutshell" von Elliotte Rusty Harold & W. Scott Means)

Außer seinen Elementen muss ein gültiges Dokument auch alle Attribute des Elements deklarieren. Dies wird mit ATTLIST-Deklarationen erledigt. Eine einzelne ATTLIST kann mehrere Attribute für einen einzelnen Elementtyp deklarieren. Tritt jedoch das gleiche Attribut bei mehreren Elementen auf, muss es auch für jedes Element, bei dem es auftaucht, getrennt deklariert werden. (Auf den folgenden Seiten werden Sie sehen, wie Sie Parameter-Entity-Referenzen einsetzen, um diese Wiederholung zu vereinfachen.)

Zum Beispiel deklariert folgende ATTLIST das Attribut quelle des Elements bild:

 

<!ATTLIST bild quelle CDATA #REQUIRED>

Sie besagt, dass das Element bild ein Attribut namens quelle besitzt. Der Wert des quelle-Attributs sind Zeichendaten, und die Angabe des Attributs quelle ist für alle Instanzen des Elements bild im Dokument erforderlich.

Eine einzelne ATTLIST-Deklaration kann mehrere Attribute für das gleiche Element deklarieren. So deklariert diese ATTLIST-Deklaration zum Beispiel nicht nur das Attribut quelle des Elements bild, sondern auch die Attribute breite, höhe und alt:

<!ATTLIST bild quelle CDATA #REQUIRED
               breite CDATA #REQUIRED
               höhe   CDATA #REQUIRED
               alt    CDATA #IMPLIED
>

Diese Deklaration besagt, dass die Attribute quelle, breite und höhe erforderlich sind. Das Attribut alt dagegen ist optional und kann bei bild-Elementen weggelassen werden. Alle vier Attribute müssen laut ihrer Deklaration Zeichendaten (CDATA) enthalten, den am häufigsten auftretenden Attributtyp.

Diese Deklaration hat die gleiche Wirkung und Bedeutung wie vier getrennte ATTLIST-Deklarationen, jeweils eine für jedes Attribut. Es ist eine Frage des persönlichen Geschmacks, ob man eine ATTLIST-Deklaration pro Attribut benutzt; die meisten erfahrenen DTD-Designer werden allerdings die mehrfache Attributform vorziehen. Wenn ausreichend Whitespace eingesetzt wird, ist diese Variante nicht schlechter lesbar als die Alternative.

Attributtypen

In lediglich wohlgeformtem XML können die Attributwerte beliebige Text-Strings sein. Die einzige Einschränkung besteht darin, dass alle eventuell auftretenden <- oder &-Zeichen mit &lt; und &amp; kodiert und damit geschützt werden müssen. Auch Anführungszeichen – egal ob einfach oder doppelt –, die verwendet werden, um Werte zu begrenzen, müssen geschützt werden. Eine DTD erlaubt Ihnen aber auch strengere Aussagen über den Inhalt von Attributwerten. Tatsächlich sind diese Aussagen strenger als diejenigen, die über den Inhalt von Elementen getroffen werden können. Zum Beispiel können Sie festlegen, dass ein Attributwert innerhalb des Dokuments einmalig sein muss, dass er ein zulässiges XML-Namenstoken oder dass er ein Wert aus einer festen Liste mit Werten sein muss.

In XML gibt es zehn Attributtypen:

  • CDATA
  • NMTOKEN
  • NMTOKENS
  • Aufzählung
  • ENTITY
  • ENTITIES
  • ID
  • IDREF
  • IDREFS
  • NOTATION

Das sind die einzigen Attributtypen, die erlaubt sind. Eine DTD kann nicht festlegen, dass ein Attributwert eine ganze Zahl oder beispielsweise ein Datum zwischen 1966 und 2004 sein muss.

CDATA

Ein CDATA-Attributwert kann jeden Text-String enthalten, der in einem wohlgeformten XML-Attributwert akzeptabel ist. Dies ist der allgemeinste Attributtyp. Sie werden diesen Typ etwa für ein alt-Attribut eines bild-Elements benutzen, da es keine bestimmte Form gibt, die der Text in einem solchen Attribut annehmen muss.

 

<!ATTLIST bild alt CDATA #IMPLIED>

Sie werden ihn auch für andere Arten von Daten benutzen, wie Preise, URLs, E-Mail- und Snailmail-Adressen, Zitate oder andere Datentypen, die zwar mehr Struktur als ein einfacher Text-String haben, aber nicht zu einem der anderen Attributtypen passen:

<!ATTLIST sku
 listenpreis               CDATA #IMPLIED
 empfohlener_verkaufspreis CDATA #IMPLIED
 tatsächlicher_preis       CDATA #IMPLIED
>
<!-- Alle drei Attribute sollten die Form $XX.YY haben. -->

NMTOKEN

Ein XML-Namenstoken ähnelt stark einem XML-Namen. Es muss aus den gleichen Zeichen bestehen wie ein XML-Name, also aus alphanumerischen und/oder ideographischen Zeichen sowie den Interpunktionszeichen _ , - , . und :. Ebenso wie ein XML-Name darf ein XML-Namenstoken darüber hinaus keinerlei Whitespace enthalten. Der Unterschied zu XML-Namen besteht darin, dass alle erlaubten Zeichen auch das erste Zeichen in einem Namenstoken bilden dürfen, während bei XML-Namen nur Buchstaben, Ideogramme und der Unterstrich als erstes Zeichen erlaubt sind. 12 und .cshrc sind deshalb zulässige XML-Namenstoken, jedoch keine gültigen XML-Namen. Jeder XML-Name ist auch ein XML-Namenstoken, jedoch ist nicht jedes XML-Namenstoken auch ein XML-Name.

Der Wert eines Attributs vom Typ NMTOKEN ist ein XML-Namenstoken. Wenn Sie zum Beispiel wissen, dass das Attribut jahr eines Elements journal einen Integer-Wert wie 1990 oder 2015 enthalten soll, könnten Sie es so deklarieren, dass es den Typ NMTOKEN besitzt, da alle Jahre Namenstoken sind:

<!ATTLIST journal jahr NMTOKEN #REQUIRED>

Diese Deklaration verhindert zwar nicht, dass der Autor des Dokuments dem Jahr Attributwerte wie 99 oder März zuweist, aber zumindest werden einige mögliche falsche Werte ausgeschlossen, vor allem solche, die Leerzeichen enthalten wie A. D. 1990 oder Sally had a little lamb.

NMTOKENS

Ein Attribut vom Typ NMTOKENS enthält ein oder mehrere XML-Namenstoken, die durch Whitespace getrennt sind. Sie könnten es z. B. benutzen, um das Attribut termine eines Elements auftritte zu beschreiben, wenn die Daten in der Form 08-26-2000 vorliegen würden:

<auftritte termine="08-21-2001 08-23-2001 08-27-2001">Kat and the Kings</auftritte>

Die entsprechende Deklaration lautet:

 <!ATTLIST auftritte termine NMTOKENS #REQUIRED> 

Andererseits könnten Sie diese Deklaration nicht für eine Liste mit Daten der Form 08/27/2001 verwenden, da der normale Schrägstrich (Slash) kein zulässiges Namenszeichen ist.

Aufzählung

Die Aufzählung ist der einzige Attributtyp, der kein XML-Schlüsselwort ist. Stattdessen ist es vielmehr eine Liste aller möglichen Werte für ein Attribut, die durch senkrechte Striche getrennt werden. Jeder mögliche Wert muss ein XML-Namenstoken sein. Die folgenden Deklarationen z. B. sagen aus, dass der Wert des Attributs monat eines Elements datum einer der zwölf Monatsnamen, dass der Wert eines Attributs tag eine Zahl zwischen 1 und 31 und dass der Wert eines Attributs jahr eine positive ganze Zahl zwischen 1970 und 2009 sein muss:

<!ATTLIST datum monat (Januar | Februar | März | April | Mai | Juni
| Juli | August | September | Oktober | November | Dezember) #REQUIRED
>
<!ATTLIST datum tag (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12
| 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25
| 26 | 27 | 28 | 29 | 30 | 31) #REQUIRED
>
<!ATTLIST datum jahr  (1970 | 1971 | 1972 | 1973 | 1974 | 1975 | 1976
| 1977 | 1978 | 1979 | 1980 | 1981 | 1982 | 1983 | 1984 | 1985 | 1986
| 1987 | 1988 | 1989 | 1990 | 1991 | 1992 | 1993 | 1994 | 1995 | 1996
| 1997 | 1998 | 1999 | 2000 | 2001 | 2002 | 2003 | 2004 | 2005 | 2006
| 2007 | 2008 | 2009 ) #REQUIRED
>
<!ELEMENT datum EMPTY>

Mit dieser DTD ist dieses Element datum gültig:

 <datum monat="Januar" tag="22" jahr="2001"/>

Diese datum-Elemente dagegen sind ungültig:

<datum monat="01"      tag="22" jahr="2001"/>
<datum monat="Jan"     tag="22" jahr="2001"/>
<datum monat="Januar"  tag="02" jahr="2001"/>
<datum monat="Januar"  tag="2"  jahr="1969"/>
<datum monat="Janvier" tag="22" jahr="2001"/>

Dieser Trick funktioniert hier, weil alle gewählten Werte zulässige XML-Namenstoken sind. Er wäre jedoch nicht möglich, wenn die möglichen Werte Whitespace oder Interpunktionszeichen außer dem Unterstrich, dem Bindestrich, dem Doppelpunkt und dem Punkt enthalten würden.

ID

Ein Attribut vom Typ ID muss einen XML-Namen (kein Namenstoken, einen Namen) enthalten, der im XML-Dokument einmalig ist. Genauer gesagt, darf kein anderes Attribut vom Typ ID im Dokument den gleichen Wert besitzen. (Attribute, die nicht vom Typ ID sind, werden dabei nicht betrachtet.) Jedes Element darf nicht mehr als ein ID-Attribut haben.

Wie das Schlüsselwort vermuten lässt, weisen ID-Attribute Elementen einen eindeutigen Identifier zu. ID-Attribute müssen nicht den Namen »ID« oder »id« haben, oft ist das jedoch der Fall. Diese ATTLIST-Deklaration beispielsweise besagt, dass jedes Element angestellter ein Attribut sozialversicherungsnummer vom Typ ID besitzen muss:

 

<!ATTLIST angestellter sozialversicherungsnummer ID #REQUIRED>

ID-Zahlen sind ein bisschen kompliziert, da eine Zahl kein XML-Name und daher keine zulässige XML-ID ist. Die einfache Lösung besteht darin, den Werten einen Unterstrich oder einen normalen Buchstaben voranzustellen. Zum Beispiel:

 

<angestellter sozialversicherungsnummer="_078-05-1120"/>

IDREF

Ein Attribut vom Typ IDREF verweist auf ein Attribut vom Typ ID eines Elements im Dokument. Es muss deshalb ein XML-Name sein. IDREF-Attribute werden üblicherweise dazu eingesetzt, um Beziehungen zwischen Elementen zu realisieren, wenn einfache Enthalten-in-Beziehungen nicht ausreichen.

Stellen Sie sich zum Beispiel ein XML-Dokument vor, das eine Liste mit projekt- und angestellter-Elementen enthält. Jedes projekt-Element hat ein projekt_id-Attribut vom Typ ID, und jedes angestellter-Element hat ein sozialversicherungsnummer-Attribut vom Typ ID. Darüber hinaus besitzt jedes projekt-Element teammitglied-Kindelemente, die kennzeichnen, wer an dem Projekt arbeitet. Da jedes Projekt mehreren Angestellten zugewiesen ist und manche Angestellte in mehreren Projekten mitarbeiten, ist es nicht möglich, die Angestellten zu Kindelementen der Projekte oder die Projekte zu Kindelementen der Angestellten zu machen. Die Lösung besteht darin, das IDREF-Attribut so zu verwenden:

<projekt projekt_id="p1">
   <ziel>Entwicklung eines strategischen Plans</ziel>
   <teammitglied person="ss078-05-1120"/>
   <teammitglied person="ss987-65-4320"/>
</projekt>
<projekt projekt_id="p2">
   <ziel>Einsatz von Linux</ziel>
   <teammitglied person="ss078-05-1120"/>
   <teammitglied person="ss9876-12-3456"/>
</projekt>
<mitarbeiter sozialversicherungsnummer="ss078-05-1120">
   <name>Fred Smith</name>
</mitarbeiter>
<mitarbeiter sozialversicherungsnummer="ss987-65-4320">
   <name>Jill Jones</name>
</mitarbeiter>
<mitarbeiter sozialversicherungsnummer="ss9876-12-3456">
   <name>Sydney Lee</name>
</mitarbeiter>

In diesem Beispiel würden das Attribut id des Elements projekt und das Attribut sozialversicherungsnummer des Elements mitarbeiter als Typ ID deklariert. Das Attribut person des Elements teammitglied wäre vom Typ IDREF. Die entsprechenden ATTLIST-Deklarationen sehen so aus:

<!ATTLIST mitarbeiter sozialversicherungsnummer ID    #REQUIRED>
<!ATTLIST projekt projekt_id                    ID    #REQUIRED>
<!ATTLIST teammitglied person                   IDREF #REQUIRED>

Diese Deklarationen erfordern es, dass das Attribut person des Elements teammitglied mit der ID von irgendetwas in dem Dokument übereinstimmt. Sie verlangen allerdings nicht, dass das Attribut person des Elements teammitglied nur mit mitarbeiter-IDs übereinstimmt. Ein teammitglied könnte auch die ID eines anderen oder sogar des gleichen Projekts enthalten. Das wäre zwar nicht unbedingt richtig, aber zumindest gültig.

IDREFS

Ein Attribut vom Typ IDREFS enthält eine durch Whitespace getrennte Liste mit XML-Namen, die jeweils die ID eines Elements im Dokument sein müssen. Es wird benutzt, wenn ein Element auf mehrere andere Elemente verweisen muss. Das vorangegangene Projektbeispiel könnte etwa dergestalt umgeschrieben werden, dass die teammitglied-Kindelemente des Elements projekt wie hier durch ein team-Attribut ersetzt werden:

<projekt projekt_id="p1" team="ss078-05-1120 ss987-65-4320">
   <ziel>Entwicklung eines strategischen Plans</ziel>
</projekt>
<projekt projekt_id="p2" team="ss078-05-1120 ss9876-12-3456">
   <ziel>Einsatz von Linux</ziel>
</projekt>
<mitarbeiter sozialversicherungsnummer="ss078-05-1120">
   <name>Fred Smith</name>
</mitarbeiter>
<mitarbeiter sozialversicherungsnummer="ss987-65-4320">
   <name>Jill Jones</name>
<mitarbeiter sozialversicherungsnummer="ss9876-12-3456">
   <name>Sydney Lee</name>
</mitarbeiter>

Die entsprechenden Deklarationen lauten:

<!ATTLIST  mitarbeiter  sozialversicherungsnummer  ID       #REQUIRED>
<!ATTLIST  projekt      projekt_id                 ID       #REQUIRED
                        team                       IDREFS   #REQUIRED>

ENTITY

Ein Attribut vom Typ ENTITY enthält den Namen eines nicht geparsten Entity, das irgendwo in der DTD deklariert wurde. Zum Beispiel könnte ein Element film ein Entity-Attribut besitzen, das die MPEG- oder QuickTime-Datei kennzeichnet, die abgespielt werden soll, wenn der Film aktiviert wurde:

<!ATTLIST film quelle ENTITY #REQUIRED>

Würde die DTD ein ungeparstes Entity namens X-Men-Trailer deklarieren, könnte dieses Element film dazu verwendet werden, diese Videodatei in das XML-Dokument einzubetten:

<film quelle="X-Men-Trailer"/>

Wir werden auf der Seite Allgemeine Entity-Deklarationen näher auf ungeparste Entities eingehen.

ENTITIES

Ein Attribut vom Typ ENTITIES enthält die Namen eines oder mehrerer ungeparster Entities, die irgendwo in der DTD deklariert wurden und durch Whitespace getrennt sind. Zum Beispiel könnte ein präsentation-Element ein Attribut ENTITIES besitzen, das JPEG-Dateien in der abzuspielenden Reihenfolge kennzeichnet:

 

<!ATTLIST diashow dias ENTITIES #REQUIRED>

Würde die DTD ungeparste Entities namens dia1, dia2, dia3 usw. bis dia10 deklarieren, könnten Sie mit Hilfe dieses Elements diashow die Show in das XML-Dokument einbetten:

 

<diashow dias="dia1 dia2 dia3 dia4 dia5 dia6 dia7 dia8 dia9 dia10"/>

NOTATION

Ein Attribut des Typs NOTATION enthält den Namen einer Notation, die in der DTD des Dokuments deklariert wurde. Das ist vermutlich der seltenste Attributtyp, und er wird in der Praxis nicht häufig eingesetzt. Theoretisch könnten Sie mit ihm bestimmten Elementen Typen zuweisen oder auch die Typen beschränken, die mit dem Element verbunden sind. Die folgenden Deklarationen z. B. definieren vier Notationen für unterschiedliche Bildtypen und legen dann fest, dass jedes bild-Element ein typ-Attribut besitzen muss, das genau eine von ihnen auswählt:

<!NOTATION gif  SYSTEM "bild/gif">
<!NOTATION tiff SYSTEM "bild/tiff">
<!NOTATION jpeg SYSTEM "bild/jpeg">
<!NOTATION png  SYSTEM "bild/png">
<!ATTLIST  bild typ NOTATION (gif | tiff | jpeg | png) #REQUIRED>

Das typ-Attribut jedes bild-Elements kann einen der vier Werte gif, tiff, jpeg oder png, jedoch keinen anderen Wert annehmen. Dieses Attribut besitzt gegenüber dem Aufzählungstyp einen leichten Vorteil, da hier der tatsächliche MIME-Typ der Notation zur Verfügung steht, wohingegen ein Aufzählungstyp bild/png oder bild/gif nicht als erlaubte Werte festlegen könnte, da der Schrägstrich in XML-Namen kein zulässiges Zeichen darstellt.

Default-Attributwerte

Außer dem Datentyp schließt jede ATTLIST-Deklaration eine Standarddeklaration für dieses Attribut ein. Dabei gibt es vier Möglichkeiten:

#IMPLIED

Das Attribut ist optional. Jede Instanz des Elements kann einen Wert für das Attribut angeben, er darf aber auch weggelassen werden. Es wird kein Default-Wert vorgegeben.

#REQUIRED

Das Attribut ist notwendig. Jede Instanz des Elements muss einen Wert für das Attribut angeben. Es wird kein Default-Wert vorgegeben.

#FIXED

Der Attributwert ist konstant und unveränderlich. Dieses Attribut hat den festgelegten Wert, unabhängig davon, ob das Attribut bei einer einzelnen Instanz des Elements explizit angegeben wird. Wird es allerdings angegeben, muss es den vorgegebenen Wert besitzen.

Literal

Der tatsächliche Default-Wert wird in Anführungszeichen angegeben.

 

Zum Beispiel besagt diese ATTLIST-Deklaration, dass person-Elemente die Attribute geboren und gestorben enthalten können, dies aber nicht tun müssen:

<!ATTLIST person geboren   CDATA #IMPLIED
                 gestorben CDATA #IMPLIED
>

Diese ATTLIST-Deklaration legt fest, dass jedes kreis-Element die Attribute mittelpunkt_x, mittelpunkt_y und radius besitzen muss:

<!ATTLIST kreis mittelpunkt_x NMTOKEN #REQUIRED
                mittelpunkt_y NMTOKEN #REQUIRED
                radius        NMTOKEN #REQUIRED
>

Diese ATTLIST-Deklaration sagt aus, dass jedes Element biographie ein Attribut version besitzen muss und dass der Wert des Attributs 1.0 ist, selbst wenn das Start-Tag des Elements nicht explizit ein Attribut version enthält:

 

<!ATTLIST biographie version CDATA #FIXED "1.0">

Diese ATTLIST-Deklaration legt fest, dass jedes Element webseite ein Attribut protokoll enthält. Besitzt ein bestimmtes webseite-Element nicht explizit ein protokoll-Attribut, wird der Parser ihm eines mit dem Wert http zuweisen:

 

<!ATTLIST webseite protokoll NMTOKEN "http">

  

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema XML bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

  


Copyright © 2005 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XML in a Nutshell" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

O’Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de