Grundbegriffe der XML-Syntax

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

I. Allgemeine Syntax-Strukturen
II. DTD (Documenttyp-Definition)
III. Der Hauptteil des Dokuments
IV. Namensräume

  

Jeder Abschnitt dieser Referenz, der sich auf eine bestimmte XML-Sprachstruktur bezieht, enthält auch eine weniger formale Beschreibung der zugehörigen Syntax. Dabei werden in den Syntaxblöcken folgende Konventionen verwendet:

Schrifttyp Bedeutung
DOCTYPE Fettdruck wird verwendet, wenn Text wortwörtlich wie im XML-Dokument dargestellt werden muss (z.B. DOCTYPE).
Zeichensatzname Kursiver Text weist den Anwender darauf hin, dass der dargestellte Text durch entsprechende Werte ersetzt werden soll. Der Text beschreibt, womit er ersetzt werden soll (z.B. Zeichensatzname = en-us).
| Der senkrechte Strich | wird verwendet, wenn ein Wert aus einer Liste möglicher Werte ausgewählt werden soll.
[ ] Eckige Klammern weisen darauf hin, dass ein bestimmter Teil der Syntax optional ist.

  


  

I. Allgemeine Syntax-Strukturen

Jedes XML-Dokument besteht aus den folgenden beiden Hauptteilen: Prolog und Wurzelelement . Einige Dokumente enthalten darüber hinaus auch Kommentare oder Verarbeitungsanweisungen, die dem Dokumentelement als eine Art Epilog folgen (keine offizielle Bezeichnung). Der Prolog enthält strukturelle Informationen über Ihr konkretes XML-Dokument. Dazu gehören unter anderem die XML-Deklaration und die DTD. Der Prolog ist optional und kann problemlos entfallen, wenn ein Dokument nicht gegen eine DTD validiert werden muss. Das oberste Dokumentelement ist der einzige Teil, den jedes wohlgeformte Dokument enthalten muss.

Die folgenden Syntax-Strukturen beziehen sich auf das gesamte XML-Dokument. Sofern nicht ausdrücklich anders angegeben, können diese Strukturen überall im XML-Dokument auftauchen.

 


Zeichen

Ihrer Natur nach sind XML-Dokumente Textdokumente, die aus Zeichen zusammengesetzt sind. Um sicherzustellen, dass Dokumente über völlig unterschiedliche Computersysteme portabel sind und Daten in so vielen menschlichen Sprachen wie möglich enthalten können, müssen XML-Parser den Unicode-Standard implementieren. Das bedeutet nicht, dass alle XML-Dokumente in Unicode gespeichert und bearbeitet werden müssen. Aber es bedeutet, dass der XML-Parser dazu in der Lage sein muss, Ihr Dokument aus seiner nativen Zeichenkodierung in Unicode zu konvertieren. Von allen XML-Parsern wird verlangt, dass sie als Kodierungsformate für die Eingabedokumente (zumindest) entweder UTF-8 oder UTF-16 unterstützen.

Anmerkung: Einer der wesentlichen Unterschiede zwischen XML 1.0 und XML 1.1 ist die Definition der Unicode-Zeichen, die innerhalb eines XML-Dokuments zulässig sind. In XML 1.0 wurde die Verwendung vieler ASCII-Steuerzeichen (wie BEL und NAK) in XML-Dokumenten ausdrücklich untersagt. XML 1.1 erlaubt beliebige Unicode-Zeichen für jedes dieser 60 Steuerzeichen (außer NUL, x0000), wenn diese durch numerische Zeichenreferenzen geschützt werden. XML 1.1 fordert außerdem, dass die C1-Steuerzeichen zwischen 0x0080 und 0x009F mit numerischen Zeichenreferenzen geschützt werden. XML 1.0 verlangte das nicht.

 


Whitespace (Leerraum)

XML 1.0 definiert Whitespace als Leerzeichen, Tabulator, Wagenrücklauf und Zeilenvorschub. XML 1.1 zählt zu Whitespace außerdem das Newline-Zeichen NEL (#x85) und den Unicode-Zeilentrenner (#x2028). Whitespace hat in XML den gleichen Sinn wie in den meisten Programmiersprachen oder im allgemeinen Sprachgebrauch: Er trennt verschiedene Syntax-Elemente. Für einen XML-Parser ist jeder Whitespace im Inhalt von Elementen signifikant und wird an das Anwendungsprogramm übergeben. Betrachten Sie dazu das folgende Beispiel:

<p>  Dieser Satz enthält
  belanglose Zeilenenden.</p>

Der Parser übergibt die Textdaten dieses Beispielelements an das Anwendungsprogramm wie folgt:

   Dieser Satz enthält
belanglose Zeilenenden.

Obwohl die XML-Spezifikation festlegt, dass jeglicher Whitespace im Elementinhalt erhalten bleibt, hat der XML-Autor die Möglichkeit, einen zusätzlichen Hinweis zu geben, dass er die Erhaltung von Whitespace und Formatzeichen ausdrücklich wünscht. Details zu diesem Thema entnehmen Sie bitte der Beschreibung des Attributs xml:space im Abschnitt »Spezielle Attribute«.

Um Software-Entwicklern das Leben zu erleichtern, sollen Parser alle Vorkommen des Wagenrücklauf-Zeichens (#xD) zu einem einzigen Zeilenvorschub-Zeichen (#xA) normalisieren. Wenn das Wagenrücklauf-Zeichen unmittelbar vor einem Zeilenvorschub-Zeichen erscheint, wird es einfach entfernt. Das führt zu einem Dokument, in dem das Ende der Zeilen von einem einzigen Zeilenvorschub-Zeichen markiert wird. In XML 1.1 erfolgt diese Normalisierung zu einem Zeilenvorschub-Zeichen auch für die Unicode-Zeichen #x85 (NEXT LINE, NEL) und #x2028 (LINE SEPARATOR).

  


Namen

XML 1.0-Namen müssen die folgenden lexikalischen Konventionen einhalten:

  • Sie beginnen mit einem Buchstaben, einem Ideograph, dem Unterstrich (_) oder dem Doppelpunkt (:).
  • Nach dem ersten Zeichen sind nur Buchstaben, Ziffern, der Punkt (.), der Bindestrich (-), der Unterstrich (_) und der Doppelpunkt (:) erlaubt.

In diesem Zusammenhang ist ein Buchstabe ein beliebiges Unicode-Zeichen, auf das die Letter-Produktionsregeln aus der XML 1.0-EBNF-Grammatik der Seite Grammatik eines XML 1.0-Dokuments zutreffen.

Anmerkung: Werfen Sie in der XML 1.1-EBNF-Grammatik einen Blick auf die Produktion für Name, wenn Sie sehen wollen, welche Zeichen in XML 1.1-Namen zulässig sind.

Die ursprüngliche XML 1.0-Spezifikation sah vor, dass das Doppelpunkt-Zeichen (:) beliebig in Namen verwendet werden darf. Allerdings ist das Zeichen jetzt als Bestandteil der Empfehlung Namensräume in XML (Namespaces in XML) offiziell reserviert. Auch wenn Sie keine Namensräume in Ihrem Dokument verwenden, sollten Sie den Doppelpunkt nur in diesem Sinn verwenden, um die Aufwärtskompatibilität zu neueren XML-Parsern sicherzustellen. Eine genauere Beschreibung zur Verwendung gültiger Bezeichner für Namensräume finden Sie im Abschnitt »Namensräume«.

Man sollte auch die Verwendung der Buchstabenfolge X, M, L zu Beginn eines Namens vermeiden (egal in welcher Groß-/Kleinschreibungsform), es sei denn, diese Buchstabenfolge wird ausdrücklich von einer XML-Spezifikation erlaubt.

  


Zeichenreferenzen

&#dezimalzahl;
&#xhexadezimalzahl;

Alle XML-Parser arbeiten intern mit Unicode als Zeichensatz. Das gilt unabhängig davon, welcher Zeichensatz im Prolog der XML-Datei angegeben wird. Theoretisch ist es möglich, Dokumente direkt in Unicode zu erstellen und zu bearbeiten. Aber viele Text-Editoren, Speichermedien und Kommunikationssysteme unterstützen den Unicode-Zeichensatz nicht vollständig. Damit Autoren von XML-Dokumenten auch in ihren existierenden Anwendungen Unicode-Zeichen verwenden können, kennt XML den Mechanismus der Zeichenreferenzen.

Eine Zeichenreferenz ermöglicht dem Autor die Einbettung je eines einzelnen Unicode-Zeichens, indem er dessen (dezimale oder hexadezimale) Nummer angibt. Stellen wir uns ein XML-Dokument vor, das den folgenden Text enthält:

 

&#xa9; 2002 O'Reilly &#38; Co

In diesem Beispiel würde der Parser die Zeichenreferenzen durch die entsprechenden Unicode-Zeichen ersetzen und den folgenden Text an das Anwendungsprogramm übergeben:

© 2002 O'Reilly & Co

Zeichenreferenzen dürfen nicht als Namensbestandteil eines Elements oder eines Attributs angegeben werden. Sie können aber in Attributwerten verwendet werden. Beachten Sie, dass die Groß-/Kleinschreibung bei hexadezimalen Zeichenreferenzen nicht berücksichtigt wird. (Beispielsweise ist &xa9; mit &xA9; äquivalent.)

  


Vordefinierte Entities

Neben den vom Anwender definierten Entities kennt XML auch die fünf benannten Entities in der folgenden Tabelle. Diese sind vordefiniert, das heißt, sie dürfen ohne vorherige Deklaration angewandt werden. Dabei handelt es sich um eine Teilmenge der in HTML-Dokumenten vordefinierten Entities:

Tabelle: Vordefinierte Entities

Entity Zeichen XML-Deklaration
&lt; < <!ENTITY lt "&#60;">
&gt; > <!ENTITY gt "&#62;">
&amp; & <!ENTITY amp "&#38;">
&apos; ' <!ENTITY apos "&#39;">
&quot; " <!ENTITY quot "&#34;">

Die Entities &lt; und &amp; müssen überall da verwendet werden, wo normalerweise < oder & in Elementinhalten und Attributwerten stehen würden. Das Entity &gt; wird häufig dazu verwendet, das Zeichen > im Inhalt eines Dokuments zu ersetzen. Diese Ersetzung ist aber nur erforderlich, um das Auftauchen der Zeichenfolge ]]> im Inhalt zu vermeiden. Die Entities &apos; und &quot; werden im Allgemeinen in Attributwerten benutzt. Dadurch sollen Konflikte zwischen dem Wert und den Anführungszeichen, die den Wert einschließen, verhindert werden.

Obwohl der Parser diese Entities auch dann korrekt umsetzt, wenn sie nicht zuvor deklariert wurden, können Sie sie in Ihrer DTD deklarieren, ohne dass dies eine Fehlermeldung hervorruft.

Die Präsenz dieser »speziellen« vordefinierten Entities im XML-Dokument stellt einen Widerspruch dar. Da man sie ohne vorherige Deklaration referenzieren kann, gibt es gültige XML-Dokumente mit Referenzen auf – streng genommen – undeklarierte Entities. Tatsächlich ist es so, dass die XML-Spezifikation Dokumentautoren rät, diese Entities explizit zu deklarieren, um ältere SGML-Parser zu unterstützen, bei denen diese Entities nicht vordefiniert werden. In der Praxis wird dadurch aber nur die Komplexität der Dokumente unnötig erhöht.

  


CDATA-Abschnitte (Textdaten)

<![CDATA[unkodierte Zeichen & Markup]]>

XML-Dokumente bestehen aus Markup und Textdaten. Die Zeichen < und & können dabei innerhalb von Textdaten nicht ohne weiteres vorkommen, sondern müssen durch Zeichen- oder Entity-Referenzen wie &amp; oder &#38; ersetzt werden. Die Referenz bewirkt, dass der Parser die Zeichen < und & nicht als Markup interpretiert, sondern sie als Teil des Datenstroms erkennt und sie an das Anwendungsprogramm übergibt.

Für größere Blöcke von Textdaten – insbesondere für Daten, die aus Markup bestehen, wie HTML oder XML-Fragmente – können CDATA-Abschnitte benutzt werden. Innerhalb eines CDATA-Abschnitts wird jedes Zeichen zwischen der Start- und End-Zeichenfolge als Zeichendaten behandelt. Auf diese Weise können spezielle Zeichen mit Ausnahme des CDATA-End-Tags ]]> ohne weiteres eingebettet werden.

CDATA-Abschnitte sind sehr nützlich, um zum Beispiel XML- oder HTML-Beispieldokumente in Tutorials über die Verwendung von XML oder HTML einzubetten. Allerdings sieht man als Inhalt von CDATA-Abschnitten in XSLT, DOM oder SAX natürlich nur reinen Text. Im Beispiel

 

<!CDATA[<a href="mailto:george@whitehouse.gov">The President</a>]]>

muss man die Mailadresse also ggf. durch Stringoperationen selbst extrahieren.

Achtung! CDATA-Abschnitte können nicht verschachtelt werden. Die Zeichensequenz ]]> darf im Textblock des CDATA-Abschnitts nicht enthalten sein, da dies ein vorzeitiges Ende des CDATA-Abschnitts darstellen würde. Im Normalfall sollte das kein Problem darstellen, aber falls Ihre Anwendung zum Beispiel XML als Textblock einbettet, sollten Sie an dieses Problem denken. Wenn Sie tatsächlich das End-Tag eines CDATA-Abschnitts in Ihren Text einbetten müssen, beenden Sie den CDATA-Abschnitt, betten diese Zeichen als Zeichenreferenzen ein und öffnen anschließend einen neuen CDATA-Abschnitt, der Ihre restlichen Textdaten enthält.

  


Entities

Ein XML-Entity kann man sich am besten als eine Art Makroprozessor vorstellen, wobei das Makro entweder vom Parser ersetzt wird (geparstes Entity, der ersetzende Text wird zu einem Teil des XML-Dokuments) oder eben nicht ersetzt wird (ungeparstes Entity, die Deklaration des Entity verweist auf externe, binäre Daten, die für den Parser nicht lesbar sind). Darüber hinaus gilt für geparste Entities, dass der ersetzende Text entweder durch einen String definiert oder aus einer externen Datei gelesen werden kann. Wird ein Entity durch den Parser ersetzt, dann durch den Text, der in der Deklaration des Entitys angegeben wurde. Der ersetzende Text wird so lange geparst, bis keine weiteren Referenzen auf Entities oder Zeichen mehr vorhanden sind.

Um das Parsen eines Dokuments zu vereinfachen, gibt es je nach Situation zwei verschiedene Typen von Entities: allgemeine Entities und Parameter-Entities. Die Syntax der Referenzierung ist in beiden Fällen nahezu identisch. Der wesentliche Unterschied besteht darin, wo diese Typen referenziert werden dürfen.

Referenzen auf Parameter-Entities

%name;

Wenn ein XML-Parser eine Referenz auf ein Parameter-Entity in der DTD Ihres Dokuments entdeckt, ersetzt er diese durch den Text des Entitys. Unabhängig davon, ob der Text wörtlich übernommen oder aus einem externen Entity eingebettet wird, setzt der Parser die Verarbeitung des ersetzenden Texts so fort, als wäre er Teil des Dokuments. Diese Vorgehensweise hat einige interessante Auswirkungen auf verschachtelte Entity-Referenzen:

<!ENTITY % JAHR "2001">
<!ENTITY COPYRIGHT "&#xa9; %JAHR;">
. . .
<copyright_hinweis>&COPYRIGHT;</copyright_hinweis>

Nach Durchführung der erforderlichen Entity-Ersetzungen führt das voherige Beispiel zu folgendem kanonischen Element:

 

<copyright_hinweis>© 2001</copyright_hinweis>

Achtung! Referenzen auf Parameter-Entities werden in XML je nach ihrer Position in der DTD unterschiedlich behandelt. Referenzen innerhalb der Werte einer Entity-Deklaration (wie zum Beispiel Copyright &#xa9; %YEAR;) sind nur als Teil einer externen Teilmenge gültig. Innerhalb der internen Teilmenge dürfen Referenzen auf Parameter-Entities nur da erscheinen, wo auch eine vollständige Markup-Deklaration verwendet werden könnte. Um es mit anderen Worten zu sagen: In der internen Teilmenge können Referenzen auf Parameter nur zum Einsetzen vollständiger Markup-Deklarationen eingesetzt werden.

Referenzen auf Parameter-Entities werden nur innerhalb der DTD verarbeitet. Demzufolge hat das Prozentzeichen % innerhalb von Textdaten keine besondere Bedeutung und muss nicht ersetzt werden.

Referenzen auf allgemeine Entities

&name;

Referenzen auf allgemeine Entities werden nur innerhalb von geparsten Textdaten im Textkörper des XML-Dokuments erkannt. Sie dürfen in den geparsten Textdaten zwischen den Start- und End-Tags sowie in Attributwerten auftreten. Innerhalb der DTD eines Dokuments oder in CDATA-Abschnitten werden sie nicht erkannt (außer in Default-Werten für Attribute).

Anmerkung: Die Verarbeitungsschritte, die auf eine von einem XML-Parser beim Parsen durchgeführte Einsetzung eines allgemeinen Entitys folgen, können zu interessanten Nebeneffekten führen. Der Text, der für das Entity eingesetzt wird, wird anschließend wiederum vom Parser gelesen. Enthält dieser Text Ersetzungen für Zeichen oder allgemeine Entities, werden diese während des Parsens ebenfalls geparst und eingesetzt.

 


Kommentare

<!-- Text des Kommentars -->

Kommentare sind überall im XML-Dokument und in der DTD erlaubt, allerdings nur außerhalb anderer Markup-Tags. XML-Parser müssen die Inhalte von Kommentar-Abschnitten nicht bestehen lassen. Daher sollte man sie nur dazu verwenden, Informationen abzulegen, die nicht von Ihrem Anwendungsprogramm benötigt werden. In der Praxis ist es besser, die Informationen, die Sie sonst in einem Kommentar-Abschnitt ablegen würden, zu einem offiziellen Teil der XML-Anwendung zu machen. Anstatt die Daten, die von einem Anwendungsprogramm gelesen und verarbeitet werden sollen, in einem Kommentar zu speichern, wie es häufig in HTML-Dokumenten gemacht wird, sollten Sie sie als Teil der Elementstruktur Ihres XML-Dokuments ablegen. In XML-Dokumenten sollten Sie Kommentare vorwiegend dazu verwenden, die Lesbarkeit einer komplexen DTD zu verbessern oder bestimmte Abschnitte zeitweise auszublenden.

Die Zeichenfolge -- darf in einem Kommentarblock nicht verwendet werden, außer als Teil des End-Tags. Da Kommentare nicht verschachtelt werden dürfen, ist es nicht möglich, einen Kommentarblock auszukommentieren.

 


Verarbeitungsanweisungen

<?target [daten der verarbeitungsanweisung]?>

Verarbeitungsanweisungen erlauben es einer XML-Anwendung, eine Anweisung an einen XML-Prozessor einzubetten, die nicht validiert werden. Das Ziel der Verarbeitungsanweisung kann ein beliebiger XML-Name sein, mit Ausnahme der Zeichenfolge xml in irgendeiner Kombination von Klein- und Großbuchstaben (siehe dazu XML-Grundlagen). Die häufigste Anwendung von Verarbeitungsanweisungen ist die Verbindung zu einem Stylesheet für die Präsentation. Es ist eines der XML-Prinzipien, Präsentation und Daten zu trennen, aber irgendein Mechanismus zur Verbindung muss letzten Endes doch vorhanden sein. Verarbeitungsanweisungen sind nur für Anwendungen von Bedeutung, die sie verarbeiten.

Der Begriff der Notation wird verwendet, um die Art der Verarbeitungsanweisung genauer zu kennzeichnen. Jede XML-Anwendung entscheidet selbst, ob und wie sie diese zusätzlichen Daten behandelt. Ein XML-Parser muss nicht reagieren, wenn er feststellt, dass eine Verarbeitungsanweisung auf eine zuvor deklarierte Notation passt. Bei der Verwendung von Notationen sollten Anwendungsprogramme, die den unbekannten PUBLIC- oder SYSTEM-Identifier des Ziels einer Verarbeitungsanweisung nicht interpretieren können, erkennen, dass sie die Daten nicht richtig interpretieren können.

 


XML-Deklaration

<?xml version="Versionsnummer" [encoding="Zeichensatzname"] [standalone="yes|no"]?>

Die XML-Deklaration hat verschiedene Aufgaben. Sie sagt dem Parser, welche Version der XML-Spezifikation verwendet wurde, wie das Dokument kodiert ist und ob ein Dokument vollständig in sich abgeschlossen ist oder nicht.

Anmerkung: Wenn Sie ein XML-Dokument erzeugen müssen, das XML 1.1-Features nutzt, müssen Sie das Pseudo-Attribut version auf 1.1 setzen:

 

<?xml version="1.1"?>

Automatische Ermittlung der Zeichenkodierung:
Die XML-Deklaration (der eventuell eine Unicode-Byte-Order-Markierung vorangeht) muss das allererste Element eines Dokuments sein, damit der XML-Parser bestimmen kann, welche Zeichenkodierung verwendet wurde, um das Dokument zu speichern. Das führt zu einem Henne-Ei-Problem mit der encoding="..."-Klausel der XML-Deklaration: Der Parser kann die Klausel nicht parsen, wenn er nicht weiß, welche Zeichenkodierung das Element verwendet. Da die ersten fünf Zeichen des Dokuments die Zeichenfolge <?xml darstellen müssen (wenn es eine XML-Deklaration enthält), kann der Parser die ersten paar Bytes eines Dokuments parsen und in den meisten Fällen die Zeichenkodierung ermitteln, bevor er die encoding-Deklaration gelesen hat.

Wenn eine XML-Deklaration vorhanden ist, muss sie am Anfang des XML-Dokuments stehen. Nichts, vielleicht mit Ausnahme eines Unicode-Verarbeitungszeichens zur Kontrolle der Byte-Reihenfolge, darf vor dem ersten Zeichen der Deklaration (<) stehen. Wenn keine XML-Deklaration vorhanden ist, wird angenommen, dass das Dokument der XML 1.0-Empfehlung folgt.

Angabe der XML-Version

... version="Versionsnummer" ...

Dieses Attribut gibt an, in welcher Version der XML-Spezifikation das Dokument verfasst wurde. Zurzeit sind die einzigen möglichen Versionsnummern 1.0 und 1.1.

Kodierungsdeklaration

... encoding="Kodierungsname" ...

Sofern die Kodierungsdeklaration vorhanden ist, gibt sie an, welche Zeichenkodierung bei der Speicherung des Dokuments verwendet wurde. Obwohl die XML-Parser intern alle Dokumente als Unicode behandeln, sind bei der Speicherung beliebige Zeichensätze erlaubt, angefangen von einer ASCII-Datei mit dem Latin-1-Zeichensatz (ISO-8859-1) bis zu einer Datei mit japanischen Zeichen.

XML-Parser können auch andere Kodierungen akzeptieren, aber die XML-Spezifikation fordert nur, dass sie Dokumente verstehen, die in UTF-8 und UTF-16 kodiert sind. Die meisten Parser unterstützen auch zusätzliche Zeichenkodierungen.

Standalone-Deklaration

... standalone="yes|no" ...

Wenn ein Dokument eine DTD verwendet und diese komplett im Dokument enthalten ist, können Sie die Deklaration standalone="yes" verwenden. Fehlt diese Deklaration, wird der Wert no angenommen, d.h., externe Entities werden gelesen und ersetzt.

Aus der Sicht des Entwicklers einer XML-Anwendung hat dieses Flag keine Bedeutung. Wenn das Flag allerdings vorhanden ist, muss der angegebene Wert korrekt sein. Der Wert standalone="yes" in einem Dokument, das eine externe DTD-Teilmenge besitzt, stellt eine Verletzung der Kriterien für die Gültigkeit eines XML-Dokuments dar.

  


  

II. DTD (Dokumenttyp-Definition)

Im Abschnitt XML-Grundlagen wurde der Unterschied zwischen wohlgeformten und gültigen XML-Dokumenten erklärt. Wohlgeformte XML-Dokumente, die eine DTD beinhalten und die von dieser DTD definierten Regeln erfüllen, heißen gültig. Dokumente, die eine DTD beinhalten, aber deren Regeln nicht erfüllen, heißen ungültig. Die DTD besteht aus der internen Teilmenge (Deklarationen, die direkt im eigentlichen XML-Dokument stehen) und der externen Teilmenge (Deklarationen, die außerhalb des eigentlichen XML-Dokuments stehen).

 


Parameter-Entities

Parameter-Entities bieten einen einfachen Makro-Ersetzungsmechanismus, der nur innerhalb des Kontexts der DTD erlaubt ist. Sie werden deklariert und können anschließend aus der DTD heraus oder auch von anderen Entity-Deklarationen referenziert werden. Der ersetzende Text kann entweder direkt angegeben oder als Inhalt einer externen Datei definiert werden. Parameter-Entities vereinfachen vor allem die Wartung von großen und komplexen Dokumenten, indem sie dem Autor die Bildung einer Bibliothek von Bausteinen erlauben.

 


Deklaration von Parameter-Entities

<!ENTITY %name "Text, der das Entity ersetzt.">
<!ENTITY %name SYSTEM "system-literal">
<!ENTITY %name PUBLIC "pubid-literal" "system-literal" >

Parameter-Entities werden in der DTD deklariert. Die Deklaration muss vor der ersten Benutzung erfolgen. Sie enthält zwei Informationen:

  • den Namen des Entitys, der bei der Referenzierung benutzt wird
  • den ersetzenden Text, entweder direkt oder indirekt durch einen Link auf ein externes Entity

Bevor Sie eine Entity-Referenz verwenden, sollten Sie sich klarmachen, dass der XML-Parser den ersetzenden Text einer Vorbehandlung unterzieht. Der wichtigste Punkt dabei ist, dass der ersetzende Text selbst Referenzen auf Parameter-Entities enthalten kann. Diese werden ggf. rekursiv ersetzt. Auch Zeichenreferenzen werden unmittelbar durch das entsprechende Zeichen ersetzt. Diese Ersetzung kann unerwartete Nebeneffekte haben, vor allem, wenn man Parameter-Entities bildet, die ihrerseits andere Parameter-Entities deklarieren. Die genaue Implementierung der Ersetzung eines Entitys durch den XML-Parser mit Hinweisen auf mögliche Nebeneffekte finden Sie in Anhang D der XML-Spezifikation 1.0.

 


Geparste allgemeine Entities

<!ENTITY name "Replacement text.">
<!ENTITY name SYSTEM "system-literal">
<!ENTITY name PUBLIC "pubid-literal" "system-literal" >

Geparste allgemeine Entities werden innerhalb der Dokumenttyp-Definition deklariert und innerhalb der Textdaten des Dokuments oder in Attributwerten referenziert. Wenn der Parser das Dokument liest, wird die Entity-Referenz durch den Entity-Text ersetzt. Der Parser nimmt seine Arbeit ebenfalls wieder auf, indem er zunächst den gerade erst eingesetzten Text bearbeitet.

Geparste allgemeine Entities werden innerhalb der DTD mit einer Syntax deklariert, die eine Obermenge der Syntax zur Deklaration von Parameter-Entities ist.

Interne Entities speichern den Ersetzungstext als literalen String. Der Ersetzungstext ist dann vollständig in der Deklaration des internen Entitys enthalten, so dass die Notwendigkeit einer externen Datei entfällt. Das entspricht weitgehend den Fähigkeiten eines Makroprozessors, wie man ihn in vielen populären Programmiersprachen und ähnlichen Umgebungen findet.

 

<!ENTITY name "Erstetzungstext">

Wenn ein geparstes allgemeines Entity referenziert wird, wird der Inhalt des externen Entitys in das Dokument eingeschlossen. Dann nimmt der Parser das Parsen wieder auf und beginnt mit dem neu eingefügten Text.

Anmerkung: Tatsächlich gibt es zwei Typen von allgemeinen Entities, die die XML-Empfehlung zulässt: geparste und ungeparste. Ein ungeparstes Entity wird mit der gleichen Syntax deklariert wie ein geparstes allgemeines Entity. Der Deklaration wird nur der Name einer XML-Notation hinzugefügt:
<!ENTITY name SYSTEM "system-literal" notationsname>
<!ENTITY name PUBLIC "pubid-literal" "system-literal" notationsname >

Ungeparste allgemeine Entities werden nicht mit der &name ;-Syntax referenziert. Um ungeparste externe Entities zu referenzieren, muss man ein Attribut mit dem Attributtyp ENTITY oder ENTITIES deklarieren. Ungeparste externe allgemeine Entities sind eines der XML-Features, die schlecht verstanden, schlecht unterstützt und in der Praxis in der Regel nicht verwendet werden. Wir empfehlen Ihnen, alternative Mechanismen zu verwenden, um externe Nicht-XML-Daten zu referenzieren. (XLinks oder einfache URI-Strings sind mögliche Optionen.)

 


Text-Deklaration

<?xml[ version="Versionsnummer"] encoding="Kodierungsname"?>

Dateien, die externe, vom Parser zu ersetzende Entities enthalten, müssen eine Text-Deklaration enthalten, wenn die Entity-Datei eine andere Zeichenkodierung als UTF-8 der UTF-16 verwendet oder ihr Inhalt der XML 1.1-Empfehlung entspricht. Nach dieser Deklaration kann dann der Text folgen, mit dem der Parser die Referenz auf das externe Entity ersetzt. Bei Entities ohne Text-Deklaration wird davon ausgegangen, dass sie der XML 1.0-Empfehlung folgen.

Anmerkung: Externe geparste Entities dürfen nur Textdaten oder eine wohlgeformte Teilmenge der DTD enthalten. Das ist eine wesentliche Einschränkung. Sie bedeutet, dass man externe Parameter-Entities nicht dazu verwenden kann, die verschiedenen Teile des XML-Syntaxbaums nach Belieben auf externe Dateien zu verteilen, die der Parser dann einsammelt.

 


Die externe Teilmenge

Teile der Dokumenttyp-Deklaration oder sogar die gesamte DTD können aus einer anderen Datei gelesen werden. Dieser Teil der DTD wird als externe Teilmenge bezeichnet. Die externe Teilmenge kann Markup-Deklarationen, bedingte Abschnitte oder Referenzen auf Parameter-Entities enthalten. Falls die DTD Features von XML 1.1 einsetzt oder die verwendete Zeichenkodierung nicht UTF-8 oder UTF-16 ist, muss die externe Datei mit einer Text-Deklaration beginnen:

 

<?xml[ version="Versionsnummer"] encoding="Kodierungsname"?>

Auf diese Deklaration (sofern vorhanden) folgt dann eine Serie vollständiger DTD-Markup-Anweisungen, darunter ELEMENT-, ATTLIST-, ENTITY- und NOTATION-Deklarationen sowie bedingte Abschnitte und Verarbeitungsanweisungen. Zum Beispiel:

<!ELEMENT moebelstueck (beschreibung, %weitere_tags; benutzer_tags?, teileliste, montageanleitung+)>

<!ATTLIST moebelstueck xmlns CDATA #FIXED "http://namespaces.oreilly.com/moebel/">
...

Interne DTD-Teilmenge

Die interne Teilmenge der DTD steht zwischen den eckigen Klammern ([ und ]) in der Deklaration des Dokumenttyps. Diese interne Teilmenge der DTD kann Markup-Deklarationen und Referenzen auf Parameter-Entities enthalten, aber keine bedingten Abschnitte. Ein Dokument kann sowohl eine interne als auch eine externe Teilmenge enthalten, die zusammen die komplette Dokumenttyp-Definition bilden. Das folgende Beispiel zeigt die interne Teilmenge zwischen den eckigen Klammern:

<!DOCTYPE moebelstueck SYSTEM "moebel.dtd"
[
<!ENTITY % buecherregal_ex SYSTEM "buecherregal_ex.ent">

%buecherregal_ex;

<!ENTITY buecherregal_pic SYSTEM "buecherregal.gif" NDATA gif>
<!ENTITY teileliste SYSTEM "teileliste.ent">
]>

  


Deklaration von Elementtypen

Deklarationen von Elementtypen stellen ein Schema für die im XML-Dokument tatsächlich enthaltenen Instanzen des jeweiligen Elementtyps dar. Diese Deklaration bestimmt, ob Elemente dieses Typs einen Inhalt haben. Falls ja, wird auch der Typ des Inhalts festgelegt. Im Folgenden werden die verschiedenen Möglichkeiten der Definition des Elementinhalts beschrieben:

Anmerkung: Auf Grund der Tatsache, dass die Empfehlung zu Namensräumen kein ausdrücklicher Bestandteil der XML 1.0-Empfehlung ist, müssen Element- und Attribut-Deklarationen in einer DTD den vollständigen (qualifizierten) Namen angeben, der im Zieldokument verwendet werden soll. Wenn Namensraum-Präfixe verwendet werden, bedeutet das, dass Elemente und Attribute in der DTD genau so deklariert werden müssen, wie sie im Instanzdokument auftreten sollen, mit Präfixen und allem anderen. Obwohl Parameter-Entities die Verwendung von verschiedenen Präfixen in Instanzdokumenten zulassen können, ist die vollständige und nahtlose Integration von Namensräumen in eine DTD-basierte Anwendung sehr umständlich.

  


Leere Elementtypen

<!ELEMENT name EMPTY>

Wird ein Element als leer deklariert, darf es weder Textdaten noch Unterelemente enthalten. Innerhalb des Dokuments findet man leere Elemente in einer der beiden folgenden Schreibweisen:

<name[attribute="wert"...]/>
<name[attribute="wert"...]></name>

  


Elementtypen mit beliebigem Inhalt

<!ELEMENT name ANY>

Der Inhaltstyp ANY dient als eine Art Platzhalter. Elemente dieses Typs dürfen nach Belieben Textdaten oder Instanzen jedes beliebigen Elementtyps enthalten, der in der DTD deklariert ist.

  


Elementtypen mit gemischtem Inhalt

<!ELEMENT name (#PCDATA [ |name]+)*>
<!ELEMENT name (#PCDATA)>

Element-Deklarationen, die das Token #PCDATA enthalten, dürfen Textdaten enthalten, evtl. gemischt mit Unterelementen, die im optionalen Bereich dieser Deklaration enthalten sind. Wird das Token #PCDATA verwendet, ist es nicht möglich, die Anzahl oder die Reihenfolge einzuschränken, in der Unterelemente mit den geparsten Textdaten gemischt werden.

  


Kindknoten mit einschränkenden Kriterien

<!ELEMENT name(kind_knoten_mit_regulaerem_ausdruck)[? | * | +]>

XML bietet eine einfache, regulären Ausdrücken ähnliche Syntax zur Festlegung der Reihenfolge und der Anzahl von Unterelementen eines Elementtyps. Dazu dienen die folgenden Operatoren:

Operator Bedeutung
Name Bezieht sich auf ein Element mit dem angegebenen Namen.
( ... ) Gruppiert Ausdrücke zu einer Verarbeitungsfolge (unter Verwendung des Kommas als Trennzeichen) oder -auswahl (mit dem | als Trennzeichen).
? Gibt an, dass der vorherige Name oder Ausdruck an dieser Stelle einmal oder keinmal vorkommen kann.
* Gibt an, dass der vorherige Name oder Ausdruck an dieser Stelle beliebig oft vorkommen kann.
+ Gibt an, dass der vorherige Name oder Ausdruck an dieser Stelle beliebig oft vorkommen darf, aber mindestens einmal vorkommen muss.

  


Deklaration einer Attributliste

<!ATTLIST elementname [attributname attributtyp default-wert-dekl]*>

In einem gültigen XML-Dokument müssen für jeden Elementtyp Attributnamen, -typen und Default-Werte der Attribute deklariert werden, die Instanzen des Elements enthalten dürfen.

Der Attributname muss den Regeln für XML-Namen entsprechen. Kein Attributname darf mehr als einmal in einer einzigen Deklaration vorkommen.

Attribut-Deklarationen geben einen bestimmten Typ für ein Attribut an. Der Attributtyp beeinflusst die Art und Weise, wie ein validierender XML-Parser Instanzen dieser Attribute in einem Dokument behandelt. Die folgende Tabelle enthält eine Liste der verschiedenen Attributtypen und ihre jeweilige Bedeutung:

Attributtyp Bedeutung
CDATA Einfache Textdaten.
ID Eine ID muss innerhalb des gesamten XML-Dokuments eindeutig sein. Keine zwei ID-Attribute dürfen denselben Wert haben, und kein Element darf mehr als ein Attribut vom Typ ID haben.
IDREF, IDREFS Eine einzelne Referenz auf eine ID (IDREF) oder eine Liste solcher Referenz-IDs (IDREFS), die durch Whitespace getrennt werden. Jedes ID-Token muss auf eine gültige ID an einer beliebigen Stelle im Dokument verweisen, die denselben Wert enthält.
ENTITY, ENTITIES Eine einzelne Referenz auf ein deklariertes, externes ungeparstes Entity (ENTITY) oder eine Liste von Referenzen auf solche Entities (ENTITIES), die durch Whitespace getrennt werden.
NMTOKEN, NMTOKENS Ein einzelnes Namenstoken (NMTOKEN) oder eine Liste von Namenstoken (NMTOKENS), die durch Whitespace getrennt werden.

  


Der Attributtyp NOTATION

... NOTATION (notation [| notation]*) ...

Der Mechanismus des NOTATION-Attributs erlaubt dem XML-Autor anzugeben, dass die in bestimmten Elementen enthaltenen Textdaten andere formale Kriterien als XML erfüllen. Das folgende Beispiel demonstriert, wie Notationen verwendet werden können, um den Typ der Programmiersprache anzugeben, der im Element code_fragment benutzt wird:

<?xml version="1.0"?>
<!DOCTYPE code_fragment
[
<!NOTATION java_code PUBLIC "Java-Quellcode">
<!NOTATION c_code PUBLIC "C-Quellcode">
<!NOTATION perl_code PUBLIC "Perl-Quellcode">
<!ELEMENT code_fragment (#PCDATA)>
<!ATTLIST code_fragment
code_lang NOTATION (java_code | c_code | perl_code) #REQUIRED>

]>
<code_fragment code_lang="c_code">
main( ) { printf("Hello, world."); }
</code_fragment>

  


 

Der Attributtyp Aufzählung

... (name_token [|name_token]*)...

Diese Syntax begrenzt die möglichen Werte des in Frage stehenden Attributs auf einen Namenstoken aus der angegebenen Liste:

<!ELEMENT tuer EMPTY>
<!ATTLIST tuer
zustand (offen | geschlossen | unbekannt) "offen">
. . .
<tuer zustand="geschlossen"/>

  


Default-Werte

Sie können einen Default-Wert angeben. Dieser wird dann vom XML-Parser an das Anwendungsprogramm übergeben, wenn kein optionales Attribut zu einem Element angegeben wurde. Die folgende Tabelle zeigt verschiedene Arten der Spezifikation eines Default-Werts für ein Attribut und ihre jeweiligen Bedeutungen:

Default-Wert Erklärung
#REQUIRED Der Wert dieses Attributs muss angegeben werden.
#IMPLIED Der Wert dieser Attributs kann angegeben werden, kann aber auch fehlen.
[#FIXED ] "default-wert" Wenn der Wert dieses Attributs nicht explizit angegeben wird, setzt der XML-Parser dafür den Default-Wert ein. Wird das Token #FIXED verwendet, muss der angegebene Wert mit dem Default-Wert übereinstimmen. In jedem Fall verfügt das Elternelement immer über ein Attribut dieses Namens.

Der Modifikator #FIXED zeigt an, dass das Attribut ausschließlich den in der Attribut-Deklaration angegebenen Wert enthalten darf. Die Angabe eines expliziten Attributwerts zu einem Element ist möglich, wenn das Attribut als #FIXED deklariert wurde, obwohl das redundant ist. Die einzige Einschränkung ist, dass der Attributwert exakt mit dem in der #FIXED-Deklaration angegebenen Wert übereinstimmen muss.

  


Spezielle Attribute

Einige Attribute haben eine spezielle Bedeutung für XML:

  • xml:space

    Das Attribut xml:space informiert die XML-Anwendung darüber, ob Whitespace im Elementinhalt von Bedeutung ist oder nicht:

    <!ATTLIST elementname xml:space (default|preserve) default-wert-dekl>
    <!ATTLIST elementname xml:space (default) #FIXED 'default' >
    <!ATTLIST elementname xml:space (preserve) #FIXED 'preserve' >

  • xml:lang

    Das Attribut xml:lang erlaubt dem Autor eines Dokuments, die Sprache anzugeben, in der der Inhalt des Elements verfasst ist. Wird dieses Attribut in einem gültigen XML-Dokument angewandt, muss die Deklaration des Elementtyps auch eine Deklaration eines Attributs mit dem Namen xml:lang enthalten. Unter Internationalisierung finden Sie Details über die Unterstützung von natürlichen Sprachen in XML.

  


Deklaration einer Notation

<!NOTATION notationsname SYSTEM "system-literal">
<!NOTATION notationsname PUBLIC "pubid-literal">
<!NOTATION notationsname PUBLIC "pubid-literal" "system-literal">

Die Deklaration einer Notation hat die Aufgabe, dem XML-Anwendungsprogramm Informationen über das Format des ungeparsten Inhalts des Dokuments zu geben. Notationen werden von ungeparsten externen Entities, Verarbeitungsanweisungen und einigen Attributwerten eingesetzt.

Die durch Notationen vermittelten Informationen haben keine Bedeutung für den XML-Parser, werden aber von dem Parser unverändert an die Client-Anwendung weitergegeben. Die Anwendung erhält auch PUBLIC- und SYSTEM-Identifier, so dass sie die Nicht-XML-Daten und Verarbeitungsanweisungen richtig interpretieren kann.

  


Bedingte Abschnitte

Die Markup-Deklarationen für bedingte Abschnitte erlauben es, Teile der externen DTD-Teilmenge nach bestimmten Bedingungen ein- oder auszublenden. In der internen Teilmenge sind bedingte Abschnitte nicht erlaubt. Das folgende Beispiel zeigt eine mögliche Einsatzmöglichkeit von bedingten Abschnitten:

<!ENTITY % debug 'IGNORE' >
<!ENTITY % release 'INCLUDE' >

<!ELEMENT addend (#PCDATA)>
<!ELEMENT result (#PCDATA)>

<![%debug;[
<!ELEMENT sum (addend+, result)>
]]>
<![%release;[
<!ELEMENT sum (result)>
]]>

  


  

III. Der Hauptteil des Dokuments

Elemente sind das A und O eines XML-Dokuments. Sie strukturieren die Textdaten und Attributwerte, die die konkrete Instanz einer XML-Dokumenttyp-Definition bilden. Die Deklarationen !ELEMENT und !ATTLIST aus der DTD beschränken die möglichen Inhalte eines Elements in einem gültigen XML-Dokument. Kombinationen von Elementen und/oder Attributen, die gegen diese Beschränkungen verstoßen, verursachen bei validierenden Parsern eine Fehlermeldung.

  


Start-Tags und End-Tags

<elementname [attributname="attributwert"]*> ...</elementname>

Elemente, die einen Inhalt haben (entweder Textdaten, andere Elemente oder gar beides), müssen mit einem Start-Tag beginnen und mit einem End-Tag aufhören.

  


Tags für leere Elemente

<elementname [attributname="attributwert"]*></elementname>
<leeres_element [attributname="attributwert"]* />

Leere Elemente haben keinen Inhalt und werden entweder mit der Start- und End-Tag-Syntax angegeben, die zuvor erwähnt wurde, oder mit der Syntax für leere Elemente. Beide Formen sind funktional identisch. Die Syntax für leere Elemente ist aber knapper und wird häufiger eingesetzt.

  


Attribute

attributname="attributwert"
attributname='attributwert'

Elemente können Attribute enthalten. Die Reihenfolge der Attribute in einem Element ist dabei bedeutungslos, und es gibt keine Garantie dafür, dass sie vom XML-Parser beibehalten wird. Die Attributwerte müssen in einfachen oder doppelten Anführungszeichen angegeben werden. Darüber hinaus müssen Attributwerte innerhalb eines Dokuments den Regeln entsprechen, die auf der Seite Einschränkungen beschrieben werden.

Beachten Sie, dass vor und nach dem Gleichheitszeichen (=) Whitespace erlaubt ist.

Der in Anführungszeichen angegebene Attributwert wird auf Gültigkeit getestet. Dabei legt der Attributtyp, der in der !ATTLIST-Deklaration des jeweiligen Elementtyps enthalten ist, fest, was genau Gültigkeit in diesem Zusammenhang bedeutet. Attributwerte dürfen Referenzen auf allgemeine Entities enthalten, aber keine Referenzen auf externe, vom Parser zu ersetzende Entities.

  


  

IV. Namensräume

Auch wenn die Unterstützung von Namensräumen kein Bestandteil der ursprünglichen XML 1.0-Empfehlung war, wurde Namensräume in XML (Namespaces in XML) doch weniger als ein Jahr später (nämlich am 14. Januar 1999) als Empfehlung angenommen. Namensräume werden dazu eingesetzt, die Namen von Elementen und Attributen in einer gegebenen XML-Anwendung eindeutig zu kennzeichnen und damit von den in einer anderen Anwendung verwendeten Namen abzugrenzen. Ausführliche Informationen darüber finden Sie unter Namensräume.

In den folgenden Abschnitten wird beschrieben, welche Auswirkungen die Verwendung von Namensräumen auf den Aufbau und die Interpretation von Element- und Attributnamen innerhalb eines XML-Dokuments hat.

  


Unqualifizierte Namen

name

Ein unqualifizierter Name ist ein XML-Element oder ein Attribut, das zu keinem Namensraum gehört. Dies könnte daraus resultieren, dass weder ein Namensraum-Präfix angegeben noch ein Default-Namensraum deklariert wurde. Alle Attributnamen ohne Namensraum-Präfix sind unqualifiziert, weil sie niemals automatisch mit einem Namensraum in Verbindung gebracht werden. XML-Parser ohne Namensraum-Unterstützung (von denen es sehr wenige gibt) oder Parser, die entsprechend konfiguriert wurden, übergeben immer unqualifizierte Namen an ihre Client-Anwendungen. Zwei unqualifizierte Namen werden als gleich angesehen, wenn sie lexikalisch identisch sind.

  


Qualifizierte Namen

[prefix:]local_part

Ein qualifizierter Name ist ein Element- oder ein Attributname, der zu einem XML-Namensraum gehört. Es gibt drei verschiedene Typen von qualifizierten Namen:

  • Elementnamen ohne Namensraum-Präfix, die im Bereich der Deklaration eines Default-Namensraums vorkommen
  • Elementnamen mit Namensraum-Präfix
  • Attributnamen mit Namensraum-Präfix

Anders als unqualifizierte Namen werden qualifizierte Namen nur als gleich angesehen, wenn ihre Namensraum-URIs (aus ihrer Namensraum-Deklaration) und ihre lokalen Teile zueinander passen.

  


Deklaration von Default-Namensräumen

xmlns="namensraum_URI"

Wenn dieses Attribut im Start-Tag eines Elements enthalten ist, werden das Element selbst und alle Elemente ohne Namensraum-Präfix, die es beinhaltet, automatisch mit dem angegebenen Namensraum-URI in Verbindung gebracht. Wird als Wert des xmlns-Attributs ein leerer String angegeben, werden Angaben von Default-Namensräumen ignoriert. Somit werden Elemente ohne Namensraum-Präfix mit keinem Namensraum in Beziehung gesetzt.

Anmerkung: Ein wichtiger Vorbehalt gegen die Deklaration von Default-Namensräumen ist, dass sie keine Auswirkung auf Attribute ohne Namensraum-Präfix haben. Attribute ohne Namensraum-Präfix gehören niemals zu einem Namensraum, selbst dann nicht, wenn das Element, das das Attribut enthält, im Namensraum enthalten ist.

  


Deklaration von Namensraum-Präfixen

xmlns:prefix="namensraum_URI"

Diese Deklaration stellt eine Verbindung zwischen dem angegebenen Namensraum-URI und dem angegebenen Namensraum-Präfix her. Ist diese Deklaration erfolgt, kann das Präfix den aktuellen Elementnamen und Attributnamen qualifizieren. Darüber hinaus können aber auch beliebige andere Elementnamen und Attributnamen innerhalb des Bereichs des Elements, in dem die Deklaration erfolgt ist, auf diese Weise qualifiziert werden. Verschachtelte Elemente können bei Bedarf ein gegebenes Präfix so umdefinieren, dass ein anderer Namensraum-URI verwendet wird, und XML 1.1-Dokumente können ein definiertes Namensraum-Präfix aufheben, indem sie es auf den leeren String setzen.

  

zum Seitenanfang

<< 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