15.2 DTDs und XML Schema
Bereits in der Einleitung wurde erwähnt, dass XML-Dokumente neben der Wohlgeformtheit zusätzlich von einem Standard abhängen können. Ein solcher Standard enthält Regeln, die bestimmen, welche Elemente und Attribute erforderlich oder zulässig sind und in welcher Reihenfolge sie stehen müssen oder dürfen. Die traditionelle Methode, um einem XML-Dokument derartige Beschränkungen aufzuerlegen, ist die Document Type Definition. Dieses Format wurde bereits für SGML entworfen und mit einigen notwendigen Änderungen und Ergänzungen für XML übernommen. Eine neuere, rein XML-basierte Alternative, die obendrein mehr Möglichkeiten bietet, ist XML Schema. Beide Sprachen werden in diesem Abschnitt behandelt.
15.2.1 Document Type Definitions (DTDs)
Eine Document Type Definition (DTD), die einen bestimmten XML-Dateityp definiert, steht in der Regel in einer externen Datei mit der Endung .dtd. Um ein XML-Dokument an die Regeln dieser DTD zu binden, müssen Sie noch vor dem Wurzelelement eine <!DOCTYPE>-Deklaration hineinschreiben. Hier wird die URL oder allgemeiner die ID der verwendeten DTD angegeben. Es kann sich dabei um eine SYSTEM-ID handeln, die stets eine URL benötigt, oder um eine PUBLIC-ID, die sich auf eine öffentlich standardisierte DTD bezieht.
Angenommen, es existiert eine DTD für das XML-Dokument aus dem vorigen Abschnitt, die sich im gleichen Verzeichnis befindet wie das Dokument. Die passende <!DOCTYPE>-Angabe verwendet in diesem Fall eine SYSTEM-ID und lautet folgendermaßen:
<!DOCTYPE comics SYSTEM "comics.dtd">
Genauso gut kann diese DTD in einem anderen Verzeichnis im Dateisystem oder sogar auf einem anderen Server im Internet liegen. Die DTD-Datei comics.dtd liegt unter anderem unter http://buecher.lingoworld.de/fachinfo/listings/15/common/comics.dtd. Wenn Sie sich auf diese URL beziehen möchten (immer mit der Gefahr, dass sie geändert oder entfernt werden könnte), funktioniert dies folgendermaßen:
<!DOCTYPE comics SYSTEM
"http://buecher.lingoworld.de/fachinfo/listings/15/common/comics.dtd">
Eine PUBLIC-ID verwendet dagegen ein standardisiertes Format, um die DTD unabhängig von ihrer konkreten URL zu kennzeichnen. Eine Anwendung, die ein Dokument auf der Grundlage dieser DTD validiert (ihre Gültigkeit überprüft), muss allerdings eine eingebaute Version der DTD enthalten oder wissen, wie sie diese online finden kann. Deshalb werden in der Praxis nur wenige öffentliche DTDs häufig verwendet. Das folgende Beispiel zeigt einen Verweis auf die XHTML-DTD des W3C:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">
Um sicherzustellen, dass die DTD auf jeden Fall gefunden wird, wenn der Validator sie benötigt, wird in der Praxis meist zusätzlich eine URL angegeben:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
Definition einer DTD
DTDs beschreiben, welche Elemente und Attribute in welcher Reihenfolge in einem Dokument zulässig sind und welche Daten sie jeweils enthalten dürfen.
Ein Element wird mithilfe einer <!ELEMENT>-Deklaration angegeben. Formal sieht diese Deklaration folgendermaßen aus:
<!ELEMENT elementname (elementinhalt)>
Der Elementinhalt kann aus einer Liste verschachtelter Elemente bestehen oder auf einfachen Textinhalt hinweisen. Enthält ein Element verschachtelte Tags, dann werden für diese wiederum <!ELEMENT>-Definitionen angegeben.
Die zulässigen Attribute für ein Element werden dagegen in eine <!ATTLIST>-Angabe geschrieben. Die formale Schreibweise ist folgende:
<!ATTLIST elementname attr1 TYP #REQUIRED
attr2 TYP #IMPLIED
...>
Der häufigste TYP für Attribute ist CDATA, also die Angabe beliebiger Zeichen. #REQUIRED oder #IMPLIED geben an, ob das Attribut erforderlich ist oder nicht. Ein Attribut mit der Angabe #REQUIRED muss angegeben werden, #IMPLIED definiert dagegen ein optionales Attribut. Eine dritte zulässige Angabe ist #FIXED, was für ein vorgegebenes Attribut steht: Wird es nicht angegeben, ist es dennoch automatisch mit seinem Standardwert vertreten; wenn Sie es explizit angeben, muss es dagegen den vorgegebenen Wert besitzen.
Übrigens können Sie auch für jedes Attribut eine eigene <!ATTLIST>-Definition schreiben. In keinem der beiden Fälle ist die Reihenfolge der Attribute innerhalb des Elements verbindlich.
Hier sehen Sie eine vollständige DTD für das eingangs vorgestellte Dokument comics.dtd. Die zusätzlich erläuterte Erweiterung um ein cover-Element für eine Abbildung des Comic-Covers ist bereits enthalten:
<!ELEMENT comics (comic+)>
<!ELEMENT comic (publisher, format, issue, title, subtitle?,
cover?, authors, price)>
<!ATTLIST comic language CDATA #REQUIRED
isbn CDATA #IMPLIED>
<!ELEMENT publisher (#PCDATA)>
<!ELEMENT format (#PCDATA)>
<!ELEMENT issue (#PCDATA)>
<!ATTLIST issue original CDATA #IMPLIED>
<!ELEMENT title (#PCDATA)>
<!ELEMENT subtitle (#PCDATA)>
<!ATTLIST cover file CDATA #REQUIRED
type CDATA #REQUIRED>
<!ELEMENT authors (author+)>
<!ELEMENT author (#PCDATA)>
<!ATTLIST author role #REQUIRED>
<!ELEMENT price (#PCDATA)>
<!ATTLIST price currency CDATA #REQUIRED>
Übrigens ist die Reihenfolge, in der Sie die Deklarationen in der DTD vornehmen, vollkommen gleichgültig. Allerdings kommen Sie leicht durcheinander, wenn Sie sich nicht dauerhaft an eine selbst gewählte Reihenfolge halten. Eine empfehlenswerte Reihenfolge, die auch im vorliegenden Beispiel verwendet wird und in vielen gut geschriebenen DTDs anzutreffen ist, funktioniert nach den folgenden Regeln:
- Als Erstes wird das Wurzelelement deklariert.
- Falls das Wurzelelement Attribute besitzt, folgt als Nächstes seine <!ATTLIST>-Deklaration.
- Anschließend werden nacheinander alle unterhalb des Wurzelelements zulässigen Elemente in der angegebenen Reihenfolge deklariert.
- Nach jedem Element folgt – falls vorhanden – seine <!ATTLIST>-Angabe; anschließend werden wiederum alle in diesem Element zulässigen Elemente durch ihre <!ELEMENT>-Angaben deklariert.
Auf diese Weise enthält die DTD ein genaues Abbild der Verschachtelung der durch sie beschriebenen XML-Dokumente. Dies können Sie zusätzlich durch Einrückungen verdeutlichen.
Die meisten Elemente in der gezeigten DTD enthalten im Übrigen keine weiter verschachtelten Elemente mehr, sondern das Inhaltsmodell (#PCDATA), also beliebigen Text. Das Element cover besitzt dagegen die spezielle Angabe EMPTY – es handelt sich um ein leeres Tag, das keine weiteren Inhalte aufweisen darf. Wie bereits erläutert, muss es später im Dokument nicht umständlich als <cover ...></cover> geschrieben, sondern kann durch <cover .../> abgekürzt werden.
Elemente deklarieren
Im vorigen Abschnitt haben Sie die <!ELEMENT>-Deklaration schon grundsätzlich kennengelernt. Die häufigsten Formen dieser Deklaration sind die Aufzählung der zulässigen Elemente oder #PCDATA für einfachen Text.
Die umfangreichste Liste von Elementen in der Beispiel-DTD enthält die Angabe für das Element comic:
<!ELEMENT comic (publisher, format, issue, title, subtitle?,
cover?, authors, price)>
In dieser Schreibweise bedeutet die Definition, dass innerhalb des Elements comic alle angegebenen Elemente in der vorgegebenen Reihenfolge vorkommen müssen. Wie hier noch genauer erläutert werden wird, bedeutet das ? hinter subtitle und cover, dass diese Elemente optional sind.
Statt einer festgelegten Reihenfolge können Sie auch eine Liste von Alternativen angeben. Das folgende Beispiel zeigt ein Element namens anschrift, das entweder das Element postfach oder strasse enthalten kann:
Die beiden folgenden Alternativen sind gültige Verwendungen des Elements anschrift:
<anschrift>
<postfach>1234567</postfach>
</anschrift>
<anschrift>
<strasse>Alte Straße 12</strasse>
</anschrift>
Solche Angaben lassen sich durch Klammern auch verschachteln. Diese verbesserte Version von anschrift verlangt entweder ein Postfach oder eine Straße und eine Hausnummer:
<!ELEMENT anschrift (postfach | (strasse, hausnr))>
Sie können sogar Alternativen und Pflichtangaben beliebig mischen, wie die folgende vollständige Fassung einer Anschrift zeigt:
<!ELEMENT anschrift (name, (postfach | (strasse, hausnr)), plz, ort)>
Eine Anschrift besteht also aus einem Namen, gefolgt von einem Postfach oder einer Straße und Hausnummer, anschließend kommt die Postleitzahl und zum Schluss der Ort. Die beiden folgenden Anschriften erfüllen dieses Format:
<anschrift>
<name>Galileo Press</name>
<strasse>Rheinwerkallee.</strasse>
<hausnr>4</hausnr>
<plz>53227</plz>
<ort>Bonn</ort>
</anschrift>
<anschrift>
<name>MICROGRAFX (Deutschland) GmbH</name>
<postfach>14 18</postfach>
<plz>85704</plz>
<ort>Unterschleißheim</ort>
</anschrift>
Alternativen können auch helfen, wenn Ihnen die Reihenfolge bestimmter Elemente egal ist. Die folgende Variante der comic-Deklaration stellt es frei, die Reihenfolge von format und issue beliebig zu vertauschen:
<!ELEMENT comic (publisher, ((format, issue) | (issue, format)),
title, subtitle?, cover?, authors, price)>
Zu viele verschiedene Reihenfolgen können Sie also nicht zulassen, weil die Liste sonst erheblich zu lang würde.
Sie können einer Liste von Alternativen auch #PCDATA voranstellen, um statt der möglichen Tags auch beliebigen Text zuzulassen. Beispielsweise könnte eine Anschrift neben einem Postfach oder einer Straße-Hausnummer-Folge auch einen anderen Zusatz enthalten, der als einfacher Text ausgedrückt wird:
<!ELEMENT anschrift (name, (#PCDATA | postfach | (strasse, hausnr)),
plz, ort)>
Auf diese Weise könnten Sie auch anders formulierte Anschriften, wie man sie manchmal in ländlichen Gegenden findet (zum Beispiel »Gutshof Erlenbach« oder Ähnliches), ohne Probleme angeben.
Jedes Element und jede Gruppe von Inhalten kann in einem XML-Dokument auch mehrmals vorkommen. Zu diesem Zweck bietet die DTD-Sprache verschiedene Modifikatoren an, die Sie hinter ein Element oder einen geklammerten Ausdruck setzen können, um seine Häufigkeit anzugeben:
- ? – Der Inhalt darf einmal oder keinmal vorkommen.
- + – Der Inhalt muss mindestens einmal vorkommen.
- * – Der Inhalt darf beliebig oft vorkommen.
Beispielsweise können Personen nicht nur einen Vornamen haben, sondern auch mehrere. Um diese Vornamen voneinander zu trennen, könnten Sie das Element author in der comics-DTD folgendermaßen verfeinern:
<!ELEMENT author (lastname, firstname+)>
Dadurch könnten Sie den Autor Brian Michael Bendis folgendermaßen angeben:
<author>
<lastname>Bendis</lastname>
<firstname>Brian</firstname>
<firstname>Michael</firstname>
</author>
Auch die Angabe ? für ein- oder keinmal kann sehr nützlich sein. Bei dem comic-Beispiel ist es etwa angebracht, Cover-Bild und Untertitel optional zu setzen, weil sie für manche Comics vielleicht nicht verfügbar sind:
<!ELEMENT comic (publisher, ((format, issue) | (issue, format)),
title, subtitle?, cover?, authors, price)>
Das Gleiche gilt für die Angabe von Postleitzahl oder Straße und Hausnummer bei Anschriften: Große Postempfänger besitzen manchmal ihre eigene Postleitzahl, die eine weitere Angabe überflüssig macht. Die ultimative Fassung des Elements anschrift sieht demnach so aus:
<!ELEMENT anschrift (name, (#PCDATA | postfach |
(strasse, hausnr))?, plz, ort)>
Der Modifikator * für beliebig oft (auch keinmal) könnte beispielsweise nützlich sein, um die Adels- oder akademischen Titel einer Person anzugeben. Die folgende Definition berücksichtigt so gut wie alle Eventualitäten bei der Angabe von Personennamen:
<!ELEMENT person (anrede, titel*, vorname+, name, geburtsname?)>
Eine Person kann nach diesem Schema beliebig viele Titel tragen, einen oder mehrere Vornamen führen und einen vom aktuellen Namen abweichenden Geburtsnamen haben oder auch nicht. Die folgenden Beispiele genügen diesem Modell:
<person>
<anrede>Herr</anrede>
<titel>Dr.</titel>
<vorname>Klaus</vorname>
<vorname>Peter</vorname>
<name>Schmitz</name>
</person>
<person>
<anrede>Frau</anrede>
<titel>Prof.</titel>
<titel>Dr.</titel>
<vorname>Annette</vorname>
<name>Schmitz</name>
<geburtsname>Müller</geburtsname>
</person>
Die folgende kleine DTD definiert ein Format für einfache Textdokumente mit wenigen Auszeichnungsmöglichkeiten:
<!ELEMENT dokument ((ueberschrift?, absatz+)+)>
<!ELEMENT ueberschrift (#PCDATA)>
<!ELEMENT absatz ((#PCDATA | fett | kursiv)+)
<!ELEMENT fett (#PCDATA)>
<!ELEMENT kursiv (#PCDATA)>
Ein Dokument kann laut dieser DTD einen oder mehrere Blöcke enthalten, die aus einer oder keiner Überschrift und einem oder mehreren Absätzen bestehen. Eine Überschrift enthält nur einfachen Text. Ein Absatz dagegen kann einen oder mehrere Teile enthalten, die aus einfachem Text, einem fetten oder einem kursiven Bereich bestehen. Die fetten oder kursiven Bereiche enthalten wiederum einfachen Text.
Das folgende kurze Beispiel zeigt ein Dokument, das sich an diese DTD hält:
<dokument>
<ueberschrift>XML</ueberschrift>
<absatz>
<fett>XML</fett> ist ein vom <kursiv>W3C</kursiv>
definiertes Metaformat für die Definition von
<kursiv>Auszeichnungssprachen</kursiv>.
</absatz>
<absatz>
Inzwischen gibt es Unmengen von Formaten, die
auf XML basieren, beispielsweise <fett>XHTML</fett>,
<fett>SVG</fett> oder <fett>RSS</fett>.
</absatz>
</dokument>
Wenn Sie das Dokument mit geeigneten Mitteln – die in diesem Kapitel noch vorgestellt werden – verarbeiten, könnte es in einem fertigen Layout zum Beispiel folgendermaßen aussehen:
XML
XML ist ein vom W3C definiertes Metaformat für die Definition von Auszeichnungssprachen. Inzwischen gibt es Unmengen von Formaten, die auf XML basieren, beispielsweise XHTML, SVG oder RSS.
Attribute definieren
Formal ein wenig einfacher, aber inhaltlich dafür komplexer als bei den Elementen sind die DTD-Regeln für die Definition von Attributen. Wie eingangs beschrieben, werden Attribute mithilfe einer <!ATTLIST>-Deklaration angegeben. Beispielsweise befindet sich in der comics-DTD die folgende Attributliste für das Element cover:
<!ATTLIST cover file CDATA #REQUIRED
type CDATA #REQUIRED>
Jede Attributangabe besteht aus dem Attributnamen (hier file und type), dem Attributtyp (im Beispiel CDATA für einen beliebigen Textinhalt) und der Angabe, ob das Attribut erforderlich ist (in diesem Fall #REQUIRED für erforderlich).
Alternativ könnten Sie die beiden Attribute des Elements cover auch folgendermaßen angeben:
<!ATTLIST cover file CDATA #REQUIRED>
<!ATTLIST cover type CDATA #REQUIRED>
Es ist mit keiner der beiden Definitionsmethoden möglich, eine bestimmte Reihenfolge der Attribute eines Elements festzulegen. Wegen der besonderen Bedeutung der Attribute als nähere Bestimmungen eines Elements wäre dies auch gar nicht wünschenswert. Es spielt überhaupt keine Rolle, ob zuerst der Dateiname oder zuerst der MIME-Type einer Comic-Cover-Abbildung angegeben wird; beide sind erforderlich, um das Bild in einer eventuellen Anwendung korrekt darstellen zu können.
Was Attributangaben besonders komplex macht, ist die Tatsache, dass es zehn verschiedene Attributtypen gibt. Der häufigste von allen ist CDATA für einen beliebigen Textstring. Fast genauso häufig wird der spezielle Inhaltstyp »Aufzählung« verwendet. Für diesen Typ wird kein spezielles Schlüsselwort angegeben, sondern lediglich eine in Klammern stehende, durch |-Zeichen getrennte Liste von Alternativen.
Beispielsweise definiert die folgende <!ATTLIST> die Attribute eines Elements namens farbe, das die Intensität einer der drei RGB-Grundfarben rot, gruen oder blau angibt:
<!ATTLIST farbe ton (rot|gruen|blau) #REQUIRED
intensitaet CDATA #REQUIRED>
Trotz der vielen verschiedenen Attributtypen gibt es keine vernünftige Möglichkeit, die Intensität auf eine ganze Zahl zwischen 0 und 255 einzuschränken – es sei denn, Sie haben Lust, statt CDATA die vollständige Liste (0 | 1 | 2 | ... | 254 | 255) einzugeben. Absolut unmöglich ist im Übrigen die Beschränkung auf einen bestimmten Datentyp wie »ganze Zahl«, »Datum/Uhrzeit« oder Ähnliches. Für solche Feinheiten ist das im weiteren Verlauf des Kapitels vorgestellte XML Schema geeigneter.
Was die verschiedenen Attributtypen dagegen zu bieten haben, sehen Sie übersichtlich in Tabelle 15.2.
Die meisten dieser Attributtypen werden Sie in eigenen DTDs wahrscheinlich niemals verwenden. Die allermeisten Aufgaben können Sie mit CDATA und Aufzählungen erledigen. Falls Sie XML für datenbankähnliche Aufgaben einsetzen, werden Sie wahrscheinlich auch ID und IDREF beziehungsweise IDREFS nützlich finden.
Die letzte Angabe innerhalb einer Attributdefinition gibt an, ob das Attribut erforderlich ist oder nicht, und besagt, ob es einen Standardwert für dieses Attribut gibt. Die vier möglichen Werte sind folgende:
- #REQUIRED – das Attribut muss auf jeden Fall angegeben werden; es gibt keinen Standardwert.
- #IMPLIED – das Attribut kann weggelassen werden; einen Standardwert gibt es auch hier nicht.
- #FIXED – das Attribut hat stets den hinter #FIXED angegebenen Standardwert. Wird es nicht angegeben, dann wird es vom Parser trotzdem mit dem Standardwert ausgewertet. Falls es explizit angegeben wird, muss es dagegen genau den Standardwert aufweisen.
- Literal – wenn Sie statt eines der drei Schlüsselwörter nur einen Standardwert in Anführungszeichen angeben, hat das Attribut diesen Standardwert, wenn Sie es weglassen. Geben Sie es dagegen explizit an, erhält es den entsprechenden Wert.
Die folgende kleine DTD definiert einen einfachen Farbverlauf aus zwei RGB-Farben. Das leere Element rgb besitzt verschiedene Attribute, um den Rot-/Grün-/Blau-Wert und die Deckkraft (alpha) zu definieren:
<!ELEMENT verlauf (rgb, rgb)>
<!ELEMENT rgb EMPTY>
<!ATTLIST rgb rot CDATA "255"
gruen CDATA "255"
blau CDATA "255"
alpha CDATA "100">
Die Standard-RGB-Farbe ist demnach Weiß mit einer Deckkraft von 100 %. Einen Verlauf von Schwarz nach Weiß, beide mit 100 % Deckkraft, können Sie also mit minimalem Aufwand folgendermaßen definieren:
<verlauf>
<rgb rot="0" gruen="0" blau="0" />
<rgb />
</verlauf>
Ein XML-Parser, der die DTD verarbeitet und diese Elemente liest, ergänzt sie automatisch zu folgender Langform:
<verlauf>
<rgb rot="0" gruen="0" blau="0" alpha="100" />
<rgb rot="255" gruen="255" blau="255" alpha="100" />
</verlauf>
Entitys
Entitys bieten vor allem die Möglichkeit, häufig vorkommende XML-Blöcke abzukürzen sowie Zeichen darzustellen, die im aktuellen Zeichensatz des XML-Dokuments nicht vorhanden sind. Im XML-Dokument werden die in der DTD definierten Entitys durch Entity-Referenzen angegeben. Die fünf fest in XML eingebauten Entity-Referenzen wurden bereits in Abschnitt 15.1.1 erläutert.
Weitere Entitys können Sie auf einfache Art und Weise innerhalb einer DTD definieren. Das folgende Entity definiert eine Copyright-Zeile:
<!ENTITY copymsg "Copyright 2013 by Galileo Computing">
Wenn Sie an irgendeiner Stelle eines XML-Dokuments, das von dieser DTD abhängt, die Entity-Referenz ©msg; verwenden, wird sie automatisch durch den String "Copyright 2013 by Galileo Computing" ersetzt. Entitys können aber nicht nur reinen Text enthalten, sondern auch XML-Auszeichnungen. Das folgende Beispiel kürzt einen vollständigen Comic gemäß der bereits vorgestellten Comic-DTD auf das Entity &comic; herunter:
<!ENTITY comic '
<comic language="en-US">
<publisher>Marvel</publisher>
<series>The Amazing Spider-Man</series>
<format>Comic Book</format>
<issue>663</issue>
<title>The Return Of Anti-Venom</title>
<subtitle>Part One: The Ghost of Jean DeWolff</subtitle>
<authors>
<author role="Writer">Dan Slott</author>
<author role="Pencils">Giuseppe Camuncoli</author>
</authors>
<price currency="USD">3.99</price>
</comic>
'>
Beachten Sie in diesem Beispiel die einfachen Anführungszeichen, in denen der Code für den Comic steht. Sie ermöglichen es, dass Sie die doppelten Anführungszeichen der enthaltenen Attributwerte einfach stehen lassen können.
Längere Entitys müssen Sie nicht innerhalb der DTD selbst definieren, sondern können sie in eine externe XML-Datei schreiben. Auf diese Datei wird dann in der Entity-Deklaration mithilfe einer SYSTEM-ID verwiesen:
Damit die Entity-Referenz &comic2; aufgelöst werden kann, muss im Verzeichnis, in dem sich die DTD befindet, eine formal korrekte XML-Datei namens comic2.xml vorliegen.
15.2.2 Namensräume
Eine besondere Eigenschaft von XML-Dokumenten besteht darin, dass Sie mehrere Dokumenttypen miteinander vermischen können. Zu diesem Zweck wurden die Namensräume (Namespaces) eingeführt, die die Unterscheidung von Elementen aus verschiedenen DTDs zulassen.
Der Standard-Namensraum eines Dokuments zeichnet sich dadurch aus, dass Sie seine Elemente ohne spezielles Präfix verwenden können. Werden weitere Namensräume eingebunden, wird deren Elementen ein Namensraum-Präfix vorangestellt, das durch einen Doppelpunkt vom eigentlichen Elementnamen getrennt wird.
Angenommen, Sie fügen in die Comic-Datei ein neues Element namens summary ein, das eine kurze Inhaltsangabe im HTML-Format enthält. Zu diesem Zweck können Sie den verwendeten HTML-Tags das Namensraum-Präfix html voranstellen, um sie von den Elementen des Standard-Namensraums zu unterscheiden. Hier ein kurzes Beispiel dazu:
<comic language="en-US">
<publisher>Marvel</publisher>
<series>Ultimate Spider-Man</series>
<format>Trade Paperback</format>
<issue original="1-13">1</issue>
<title>Ultimate Spider-Man</title>
<subtitle>Ultimate Collection</subtitle>
<authors>
<author role="Writer">Brian Michael Bendis</author>
<author role="Pencils">Mark Bagley</author>
</authors>
<summary>
<html:p>
Der erste Band der Sammelausgabe von
<html:i>Ultimate Spider-Man</html:i> beschreibt, wie
der Schüler <html:b>Peter Parker</html:b> zum Superhelden
<html:b>Spider-Man</html:b> wird und seine ersten Abenteuer
erlebt.
</html:p>
</summary>
<price currency="USD">24.99</price>
</comic>
Die im Element summary verwendeten HTML-Auszeichnungen definieren einen Absatz, Fett- und Kursivschrift. Sie werden in Kapitel 17, »Webseitenerstellung mit (X)HTML und CSS«, genauer erläutert.
Namensräume werden mithilfe von xmlns-Angaben innerhalb eines Elements in das Dokument eingebunden. In der Regel stehen sie im Wurzelelement. Der Standard-Namensraum wird einfach als xmlns bezeichnet, während zusätzliche Namensräume mit xmlns:namensraum angegeben werden. Das folgende Beispiel bindet das comics-Format als Standard-Namensraum und das HTML-Format als Erweiterung ein:
<comics
xmlns="http://buecher.lingoworld.de/fachinfo/listings/15/common/comics" xmlns:html="http://www.w3.org/1999/xhtml">
Unter den angegebenen URLs muss sich kein spezielles Dokument befinden, das den Namensraum definiert – allerdings ist es üblich, dort eine kurze Beschreibung des Namensraums im HTML-Format abzulegen. Wichtig ist nur, dass verschiedene Namensraum-Angaben auch unterschiedliche URLs verwenden.
15.2.3 XML Schema
XML Schema bietet eine alternative Möglichkeit, Standards für XML-Dokumente einzurichten. Gegenüber DTDs besitzt dieses Format vor allem zwei Vorteile:
- Die zulässigen Inhalte für Elemente und Attribute können wesentlich genauer angegeben werden.
- Das Format ist selbst XML-basiert, verwendet also keine separate Syntax wie DTDs, sondern besteht aus wohlgeformten XML-Dokumenten.
Eine Schema-Definition steht in einer Datei mit der Endung .xsd. Die meisten aktuellen XML-Parser unterstützen ein Schema als Alternative zu einer DTD für die Validation von Dokumenten.
Hier ein einfaches Schema für Adresslisten-Dokumente auf der Basis des zuvor definierten Adressbeispiels:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="adressliste">
<xs:complexType>
<xs:element name="person" minOccurs="1"
maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="anrede"
type="xs:string" />
<xs:element name="titel" type="xs:string"
minOccurs="0" />
<xs:element name="vorname" type="xs:string"
maxOccurs="unbounded" />
<xs:element name="name" type="xs:string" />
<xs:element name="anschrift">
<xs:complexType>
<xs:choice>
<xs:element name="strasse"
type="xs:string" />
<xs:element name="plz"
type="xs:string" />
</xs:choice>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:complexType>
</xs:element>
</xs:schema>
Grundsätzlich wird jedes Element mithilfe einer <xs:element>-Deklaration angegeben. Elemente, die nur einfachen Textinhalt und keine verschachtelten Elemente oder Attribute besitzen, benötigen im Schema das Attribut type, das den zulässigen Typ des Inhalts angibt. Einige zulässige Typen sind "xs:string" für beliebigen Text, "xs:integer" für ganze Zahlen oder "xs:language" für eine ISO-Sprachangabe wie en (Englisch) oder de (Deutsch). Diese und andere Inhaltstypen können sowohl für Elemente als auch für Attribute verwendet werden.
Elemente, die verschachtelte Elemente, gemischten Inhalt oder Attribute enthalten dürfen, benötigen zur Angabe dieser Komponenten einen <xs:complexType>-Block. Für verschachtelte Elemente steht innerhalb dieses Blocks entweder ein einzelnes Element, eine durch einen <xs:sequence>-Abschnitt umschlossene Liste aufeinanderfolgender Elemente oder eine durch <xs:choice> umhüllte Aufzählung von Alternativen.
Attribute – die im zuvor gezeigten Beispiel nicht vorkommen – werden übrigens folgendermaßen deklariert:
<xs:attribute name="isbn" type="xs:integer" />
Angenommen, Sie möchten ein Element buchtitel deklarieren, dessen Inhalt einfacher Text ist und das ein Attribut namens isbn enthält. Da Elemente mit Attributen immer einen <xs:complexType>-Block benötigen, in dem ihr Inhalt definiert wird, können Sie nicht mehr einfach type="xs:string" schreiben. Stattdessen sieht die Definition nun so aus:
<xs:element name="buchtitel">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="isbn" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
Der <xs:simpleContent>-Block gibt an, dass das Element trotz des <xs:complexType> nur einfachen Inhalt und keine verschachtelten Tags enthält. <xs:extension> gibt den Inhaltstyp des Elements selbst an (hier "xs:string"), während die hineinverschachtelten <xs:attribute>-Elemente die Attribute und ihre Datentypen definieren.
Interessant ist schließlich noch die Möglichkeit, über minOccurs und maxOccurs die minimale und die maximale Anzahl von Elementen eines Typs anzugeben. Beide haben den Standardwert 1; ein Element ohne weitere Angaben muss genau einmal vorkommen. Ein spezieller Wert für maxOccurs ist "unbounded". Das entsprechende Element darf unbegrenzt oft vorkommen.
Das folgende kurze Beispiel genügt dem in diesem Abschnitt definierten Schema und zeigt außerdem, wie Sie die Verwendung des Schemas im XML-Dokument angeben:[Anm.: Die hier sehr verkürzt behandelte Schema-Spezifikation wird noch erheblich komplexer, wenn Namensräume ins Spiel kommen. xsi:noNamespaceSchemaLocation bindet nur Schema-Definitionen ein, die keine speziellen Namensräume deklarieren.]
<?xml version="1.0"?>
<adressliste xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="adressen.xsd">
<person>
<anrede>Herr</anrede>
<titel>Doktor</titel>
<vorname>Dieter</vorname>
<name>Heinze</name>
<anschrift>
<strasse>Alte Straße 34</strasse>
</anschrift>
</person>
<person>
<anrede>Frau</anrede>
<vorname>Maria</vorname>
<vorname>Theresia</vorname>
<name>Huber</name>
<anschrift>
<postfach>1234567</postfach>
</anschrift>
</person>
</adressliste>
Über dieses kurze Beispiel hinaus ist XML Schema eine sehr umfangreiche Sprache, die sehr detaillierte Definitionen für Dokumentformate ermöglicht. Der in diesem Abschnitt gewährte kleine Einblick hat hoffentlich gezeigt, dass die Möglichkeiten von Schema weit über DTDs hinausgehen.
Ihr Kommentar
Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.