Websiteentwicklung: XML: Aufbau eines XML-Dokumentes
Die Struktur eines XML-Dokumentes
BearbeitenEin erstes XML-Dokument
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE WurzelElement SYSTEM "index.dtd">
<!-- Unser erstes XML-Dokument. -->
<WurzelElement>
<Inhalt>Erstes XML-Dokument</Inhalt>
<Text>Das erste Beispiel für ein
wohlgeformtes XML-Dokument
</Text>
</WurzelElement>
<!-- Ende des XML-Dokumentes -->
Dies ist ein wohlgeformtes XML-Dokument. Jedes XML-Dokument besteht dabei aus dem Prolog, dem Wurzelelement (und seinen Inhalten) sowie bestimmten optionalen Strukturen nach dem Wurzelelement, die nicht mehr zum eigentlichen Inhalt des Dokumentes gehören, in dem Beispiel sind das Leerzeichen und ein Kommentar.
In Kurznotation sieht die Definition eines Dokumentes wie folgt aus:
document ::= prolog element Misc*
Dabei werden die Begriffe prolog und element in folgenden Abschnitten definiert.
Definition von Misc:
Misc ::= Comment | PI | S
Die Begriffe Comment (Kommentar) und PI (Verarbeitungsanweisung) werden ebenfalls in folgenden Abschnitten definiert.
S steht für Leerzeichen:
S ::= (#x20 | #x9 | #xD | #xA)+
Prolog
BearbeitenBeispiel für einen Prolog:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE WurzelElement SYSTEM "index.dtd">
<!-- Unser erstes XML-Dokument. -->
Der Prolog geht dem eigentlichen Dokumentinhalt voran und beinhaltet formale Informationen, die für die Interpretation des Inhaltes oder dessen Präsentation relevant sind, wobei hier Interpretation primär im technischen Sinne zu verstehen ist, also wie man den Dokumentinhalt verarbeitet, wie er strukturiert oder kodiert ist.
In Kurznotation sieht die Definition eines Prologs wie folgt aus:
prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
Die Begriffe XMLDecl und doctypedecl werden später noch definiert, Misc siehe oben.
XML-Deklaration
BearbeitenDer Prolog besteht zunächst aus der XML-Deklaration <?xml version="1.0" encoding="UTF-8"?>
,
welche die Version des XML-Dokumentes angibt, mit der das Dokument verfasst wurde.
Autoren sollten eine XML-Deklaration am Anfang eines XML-Dokumentes notieren.
Wird die XML-Deklaration notiert, so steht sie immer am Anfang des Dokumentes, davor sollen also keine weiteren Zeichen stehen.
Es gibt die Versionen 1.0 und 1.1. Zu Version 1.0 gibt es eine korrigierte erneute Veröffentlichung. Weil darin entscheidende Probleme dieser Version behoben sind, wird meist 1.0 verwendet, 1.1 wird meistens als nicht relevant eingestuft. Wenn es also keine bestimmten Gründe für die Verwendung von 1.1 gibt, ist 1.0 die richtige Wahl.
Die XML-Deklaration wird wie eine Verarbeitungsanweisung notiert, wird in der Empfehlung allerdings Deklaration genannt.
<?xml ?>
ist das Gerüst dieser Konstruktion, darin sind Pseudo-Attribute notiert, mit Leerzeichen voneinander und dem Anfang separiert sind.
Ein Pseudoattribut besteht aus einem Namen, also etwa version, gefolgt von einem Gleichheitszeichen, gefolgt von einem
Wert, der in Anführungszeichen notiert wird, entweder in einfachen oder in doppelten.
version ist also das Pseudoattribut für die verwendete XML-Version, in Frage kommen also version='1.0' oder version='1.1'.
Nach der Versionsangabe kann ein Pseudoattribut encoding mit der Angabe der im Dokument verwendeten Kodierung folgen. Ist nichts angegeben, wird UTF-8 angenommen. Programme, die das Dokument verarbeiten, können allerdings auch aus anderen Quellen Informationen mit höherer Priorität über die Kodierung bekommen. Die Angabe im Dokument wird dann berücksichtigt, wenn es solche Quellen nicht gibt, ist aber natürlich auch nützlich, um bei manueller Bearbeitung mit einem Texteditor etwa daran zu erinnern, mit welcher Kodierung zu arbeiten ist.
Das Problem der Kodierung ist allen digitalen Formaten gemein, ohne äußere Information darüber, welche Folge von Bits auf einem Speichermedium welche Bedeutung haben, gibt es keine definierte Information. Auch auf höherer Abstraktionsebene, etwa dem Dateisystem gibt es aus historischen Gründen keine einfache, für Nutzer direkt zugängliche Möglichkeit, Metainformation wie die Kodierung einer Datei direkt und normativ mit der Datei zu verknüpfen, daher wird an dieser Stelle immer irgendwie improvisiert. Auch bei der XML-Lösung mit dem Prolog handelt es sich um eine Improvisation. Offenbar ist die XML-Deklaration bereits zu dekodieren, bevor man die Angabe zur Kodierung auswerten kann. Praktisch funktioniert das bei XML allerdings recht gut, weil die in der XML-Deklaration verwendeten Zeichen in den üblichen Kodierungen immer gleich sind.
Nach dem Pseudo-Attribut zur Kodierung kann noch ein weiteres Pseudo-Attribut notiert sein, welches Auskunft darüber gibt, ob die Interpretation des Dokumentes von äußeren Quellen abhängen kann oder nicht. Dies ist das Pseudo-Attribut standalone, es hat entweder den Wert 'yes' oder 'no'. Ist das Pseudo-Attribut nicht notiert, wird 'no' angenommen. Wann zum Beispiel hängt die Interpretation eines Dokumentes von äußeren Quellen ab? Dies ist etwa der Fall, wenn das XML-Format für nicht gesetzte Attribute Werte als Voreinstellung definiert oder auch Entitäten (Abkürzungen) für Konstrukte festlegt und diese im Dokument verwendet werden. Oftmals gibt es solche Festlegungen, etwa auch für XHTML (sowohl voreingestellte Attributwerte als auch Entitäten) und SVG (voreingestellte Attributwerte, die von zentraler Bedeutung für die korrekte Interpretation eines Dokumentes sind). Selbst wenn es keine solche externen Festlegungen gibt, ist 'no' nicht falsch, weswegen es in vielen Fällen sinnvoll ist, das Pseudo-Attribut nicht explizit zu setzen, um diese Frage offenzulassen. Umgekehrt, setzt man explizit standalone="yes", so gibt man damit verbindlich an, dass es solche Abhängigkeiten von anderen Informationen nicht gibt, was es natürlich vereinfachen kann, ein Dokument in einem unbekannten XML-Format sicher zu interpretieren. Bei SVG etwa müßte man dann vorsichtshalber alle Attribute explizit setzen, welche voreingestellte Werte haben. Bei XHTML etwa dürfte man keine für das Format spezifischen Entitäten notieren, nur die numerischen.
Nach der XML-Deklaration können Leerzeichen, Kommentare und Verarbeitungsanweisungen folgen, zur Notation von Kommentaren gibt es später noch einen Abschnitt.
Kurznotation für die Deklaration:
XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>'
VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"')
Eq ::= S? '=' S?
VersionNum ::= '1.' [0-9]+
EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" )
EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"'))
Typische Beispiele
BearbeitenNur eine Angabe, dass nach XML1.0 zu interpretieren ist. Sofern keine anderen Angaben gemacht wurden, wird UTF-8 als Kodierung unterstellt:
<?xml version="1.0" ?>
Zusätzliche Angabe der Kodierung als ISO-8859-1 (das reicht für Umlaute, ß-Ligatur und einige andere Sonderzeichen aus dem europäischen Sprachraum):
<?xml version="1.0" encoding="ISO-8859-1" ?>
Beziehungsweise wenn man das Euro-Zeichen braucht, kann auch ISO-8859-15 verwendet werden:
<?xml version="1.0" encoding="ISO-8859-15" ?>
Eine Kodierung mit UTF-8 eignet sich für die meisten Sprachen und kann insbesondere empfohlen werden, wenn neu angefangen wird und keine Altlasten mit anderer Kodierung bereits vorhanden sind.
<?xml version="1.0" encoding="UTF-8" ?>
Zu beachten ist, dass einige Editoren bei UTF-8 an den Beginn einer Datei bisweilen ein BOM setzen (Byte-Anordnungsmarkierung, englisch: byte order mark). Das ist für UTF-8 nicht unbedingt notwendig, weil dort die Anordnung der Bytes eindeutig ist. Dies kann aber mit der Forderung kollidieren, dass zu Beginn des Dokumentes die XML-Deklaration stehen soll. Entwicklern einiger Programme ist das Problem bekannt und sie umgehen es, indem sie das vorangestellte BOM hinsichtlich der Forderung ignorieren, dass die XML-Deklaration zu Beginn des Dokumentes stehen soll. Bei anderen Programmen oder älteren Versionen kann es hingegen passieren, dass versucht wird, das BOM zur Anzeige zu bringen, statt ein XML-Dokument zu verarbeiten. Deswegen ist es in der Praxis empfehlenswert, dem Editor nicht zu erlauben, ein BOM an den Anfang einer mit UTF-8 kodierten XML-Datei zu setzen und das XML-Dokument damit formal oder auch ganz praktisch ungültig zu machen.
Beispiel mit der Angabe, dass keine externen Informationsquellen zur Interpretation notwendig sind:
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
Beispiel mit folgendem Kommentar:
<?xml version="1.0" ?>
<!-- Dokument erstellt von Rainer Zufall
in Zusammenarbeit mit einem winzigweichen Programm
-->
Verarbeitungsanweisungen, insbesondere XML-Stilvorlagenverarbeitungsanweisungen
BearbeitenVerarbeitungsanweisungen (englisch: processing instructions) dienen dazu, den Programmen oder Anwendungen, welche das Dokument verarbeiten oder interpretieren, Anweisungen zur Verarbeitung zu geben. Der Inhalt der Verarbeitungsanweisung kann spezifisch für das Programm oder die Anwendung sein, aber auch für den Zweck.
Eine Verarbeitungsanweisung beginnt mit '<?' und endet mit '?>', wirkt also ähnlich wie eine Markierung. Direkt nach dem '<?' folgt der Name des Ziels der Verarbeitungsanweisung. Der Name ist meist eine Buchstabenfolge. Zu Details der Namensproduktion siehe auch den Abschnitt über Wohlgeformtheit. Sofern die Verarbeitungsanweisung weitere Zeichen enthält, folgt hinter dem Namen ein Leerzeichen, darauf können weitere Zeichen folgen, ausgenommen '?>', was für das Ende der Verarbeitungsanweisung vorbehalten ist. Zumeist hat die Verarbeitungsanweisung zwischen Anfang und Ende mit Leerzeichen separierte Pseudo-Attribute, die genau wie XML-Attribute zu notieren sind.
Kurznotation für Verarbeitungsanweisungen:
PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
Der Begriff Name beschreibt die Namensprodukt, wie in einem späteren Abschnitt genauer erläutert wird.
Ein typischer und häufig verwendeter Vertreter unter den Verarbeitungsanweisungen ist die von XML vordefinierte XML-Stilvorlagenverarbeitungsanweisung. XML-Stilvorlagenverarbeitungsanweisungen können also auf die XML-Deklaration folgen und referenzieren dann externe Dateien, in denen Stilvorlagen notiert sind. Auf eine XML-Stilvorlagenverarbeitungsanweisung können optional auch wieder Leerzeichen und Kommentare folgen. XML-Stilvorlagenverarbeitungsanweisungen sind primär sinnvoll, wenn man das Dokument nicht nur automatisch verarbeiten will, sondern auch (menschlichen) Nutzern präsentieren, etwa in einer graphischen oder akustischen Ausgabe.
Folgendes ist ein Beispiel mit XML-Stilvorlagenverarbeitungsanweisungen. Hier werden CSS-Dateien referenziert. Eine andere geläufige Möglichkeit für eine Stilvorlagensprache ist XSL(T), ebenfalls ein XML-Format.
Bei dem Beispiel gibt es drei verschiedene Vorlagen. Das Darstellungsprogramm sollte einen Auswahlmechanismus bereitstellen, um zwischen den drei Möglichkeiten zu wechseln (ist zum Beispiel mit Mozilla-Geckos oder Opera-Presto auch nachvollziehbar).
Die Verarbeitungsanweisung hat jeweils wieder Pseudo-Attribute, im Folgenden der Einfachheit halber nur Attribute genannt.
<?xml version="1.0" encoding="UTF-8" ?>
<!-- hier kommen die Stilvorlagen: -->
<?xml-stylesheet href="css1.css" type="text/css" title="Stil 1"?>
<?xml-stylesheet href="css2.css" type="text/css" title="Stil 2"
alternate="yes" ?>
<?xml-stylesheet href="css0.css" type="text/css" title="Kein CSS"
alternate="yes" ?>
<!-- das waren die Stilvorlagen -->
Mit dem Attribut href wird die externe Stilvorlage referenziert. Die Angabe des Attributes ist erforderlich. Der Attributwert ist eine absolute oder relative URI der Datei mit der Stilvorlage, hier einfach der Dateiname einer CSS-Datei im gleichen Verzeichnis. Es kann auch eine Referenz auf einen Fragmentidentifizierer sein, also ein Verweis auf ein Dokumentfragment, welches die Stilvorlage enthält. Dies impliziert, dass das verwendete Format über ein Attribut verfügt, welches der Identifikation von Fragmenten dient, auch das für XML allgemein verwendbare Attribut xml:id hat diesen Zweck (siehe entsprechenden Abschnitt zu vordefinierten XML-Attributen). Bei Fragmentidentifizierern, welche für ein Format spezifisch sind, muß das verwendete Darstellung diese Funktion natürlich kennen, etwa über den internen Teil der Dokumenttypdefinition (siehe entsprechendes Kapitel).
Mit dem Attribut type wird angegeben, welches Stilvorlagenformat verwendet wird, hier also CSS. Der Wert ist ein Medientyp oder Inhaltstyp (ehemals MIME-Typ). Die Angabe des Attributes ist erforderlich.
Mit dem Attribut title kann ein Titel oder eine Überschrift angegeben werden. Die Angabe des Attributes ist nicht erforderlich, sie wird jedoch immer benötigt, wenn mehrere Stilvorlagen alternativ angeboten werden. Das Attribut ist also insbesondere relevant, wenn das Darstellungsprogramm mehrere alternative Stilvorlagen zur Auswahl stellen soll, der Attributwert wird dann als Menüeintrag der Auswahl verwendet.
Dass Stilvorlagen alternativ und nicht alle gleichzeitig angewendet werden sollen, wird dann mit dem Attribut alternate angegeben. Die erste Angabe im obigen Beispiel ist ohne alternate, was dann bedeutet, dass dies die Voreinstellung ist. Der Attributwert 'yes' gibt eben an, dass es sich um eine alternative Stilvorlage handelt. 'no' würde angeben, dass es zusätzlich zur Voreinstellung anzuwenden ist. Eine Angabe des Attributes ist nicht erforderlich, Voreinstellung ist 'no'.
Mit dem Attribut charset kann ein Hinweis auf die Kodierung des referenzierten Dokumentes angegeben werden. Eine Angabe des Attributes ist nicht erforderlich. Die möglichen Werte entsprechen denen von encoding. Der Hinweis ist allerdings nur relevant, wenn es keine anderen bindenden Informationen gibt, zum Beispiel von einem Dienstrechner oder Dienstprogramm, welche das referenzierte Dokument ausliefern, oder im Dokument selbst.
Mit dem Attribut media kann angegeben werden, für welches Ausgabemedium die Stilvorlage gedacht ist. Eine Angabe des Attributes ist nicht erforderlich, Voreinstellung ist in CSS 'screen'. Der Attributwert ist ein Medientyp oder eine Liste von Medientypen, die jeweils mit einem Komma voneinander separiert sind. Welche Medientypen verfügbar sind, hängt von der verwendeten Stilvorlagensprache ab. CSS2 gibt zum Beispiel folgende Möglichkeiten an:
- all
- Für alle Ausgabemedien geeignet.
- aural
- Für eine akustische Wiedergabe vorgesehen.
- braille
- Für Braille-Geräte vorgesehen.
- embossed
- Für Braille-Seitendrucker vorgesehen.
- handheld
- Für Handheld-Geräte vorgesehen (normalerweise mit kleinem Schwarzweißbildschirm und begrenzter Bandbreite).
- Für Drucker vorgesehen, ebenso für den Druckvorschaumodus auf dem Bildschirm.
- projection
- Für projizierte Präsentationen vorgesehen, wie zum Beispiel Projektoren oder den Ausdruck auf Folien.
- screen
- Hauptsächlich für normale Farbmonitore vorgesehen.
- tty
- Für Medien vorgesehen, die ein festes Zeichenraster verwenden, wie beispielsweise Fernschreiber oder Terminals.
- tv
- Für fernsehartige Geräte vorgesehen (geringe Auflösung, begrenzt rollbare Bildschirme, aber in Farbe und mit Ton).
Für spätere Versionen von CSS sind weitere Typen und Schreibweisen vorgesehen, insbesondere auch, weil es inzwischen eine größere Anzahl von verschiedenen Geräten gibt. Zum Beispiel weichen bei Notebooks oder Mobiltelephonen die typischen Abmessungen von Höhe und Breite erheblich von denen von anderen Monitoren ab (auch im Seitenverhältnis).
Dokumenttypdeklaration
BearbeitenOptional folgt die Dokumenttypdeklaration, optional gefolgt von Leerzeichen, Kommentaren und Verarbeitungsanweisungen. Mit der Dokumenttypdeklaration wird auf ein maschinenlesbares Schema in einer eigenen Sprache verweisen. Dies ist die Dokumenttypdefinition. Die eignet sich dazu, das Dokument zu validieren. Sowohl in der Dokumenttypdeklaration als auch in der Dokumenttypdefinition können weitere Definitionen stehen, beliebt sind insbesondere auch Abkürzungen, sogenannte Entitäten für besondere Strukturen, aber auch vordefinierte Attributwerte.
Kurznotation:
doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' intSubset ']' S?)? '>'
intSubset ::= (markupdecl | DeclSep)*
DeclSep ::= PEReference | S
markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment
ExternalID ::= 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral
PEReference ::= '%' Name ';'
SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
Der Begriff Comment (Kommentar wird in einem späteren Zusammenhang erläutert. markupdecl und darin genannte Begriffe werden im Kapitel Dokumenttypdefinition näher erläutert.
Wurzelelement und dessen Inhalt
BearbeitenNach dem Prolog folgt das Wurzelelement (englisch: root element). Dies kann leer sein, aber auch weitere Inhalte enthalten. Derartiger Inhalt ist Text, Kommentare, Verarbeitungsanweisungen und weitere Elemente. Was davon und gegebenenfalls gar in welcher Reihenfolge auftreten kann, ist im jeweiligen Format festgelegt.
Im Beispiel sieht das samt Inhalt so aus:
<WurzelElement>
<Inhalt>Erstes XML-Dokument</Inhalt>
<Text>Das erste Beispiel für ein
wohlgeformtes XML-Dokument
</Text>
</WurzelElement>
Ein XML-Dokument hat immer exakt ein Wurzelelement, welches alle Inhalte umschließt.
Elementnotation
BearbeitenElemente allgemein beginnen mit einer Anfangsmarkierung und enden mit einer Endmarkierung. Eine Markierung beginnt mit dem Zeichen '<' und endet mit dem Zeichen '>'.
Bei der Endmarkierung folgt auf '<' das Zeichen '/' und dann der Name des Elementes, direkt gefolgt vom '>'. Vor dem '>' können noch Leerzeichen stehen.
Der Name ist eine Zeichenfolge, meist Buchstaben, die sinnvoller Weise grob zum Ausdruck bringen, was das Element repräsentiert, wozu das Element dient oder was die Bedeutung seines Inhaltes ist. Ein anderer Aspekt bei der Namensgebung ist Effektivität - häufig verwendete Elemente sollten möglichst kurze Namen haben, um Arbeit bei der Erstellung von Dokumenten zu sparen, aber auch Speicherplatz. Bei seltener verwendeten Elementen wird man hingegen einen suggestiven, längeren Namen vorziehen, um die intuitive Verständlichkeit und Lesbarkeit des Formates zu optimieren. Formale Angaben zu den erlaubten Zeichen sind im Abschnitt Wohlgeformtheit erwähnt.
Bei der Anfangsmarkierung folgt auf das '<' der Elementname. Nach Leerzeichen können dann in der Anfangsmarkierung Attribute mit ihren Wertzuweisungen folgen. Mit Attributen kann näher und im Detail angegeben werden, was das Element repräsentiert, wozu das Element dient oder was die Bedeutung seines Inhaltes ist. Die Verwendung von Attributen bietet also die Möglichkeit einer feineren Unterscheidung zwischen Elementen mit demselben Namen.
Attribute werden voneinander mit mindestens einem oder auch mehreren Leerzeichen separiert. Hinter dem letzten Attribut dürfen weitere Leerzeichen folgen. Dasselbe Attribut kann exakt einmal pro Element notiert werden, die Reihenfolge der notierten Attribute spielt keine Rolle. Ein Attribut wird mit seinem Namen notiert, die sinnvolle Wahl der Attributnamen folgt den gleichen Kriterien wie bei der Wahl eines Elementnamens.
Auf den Attributnamen folgt ein Gleichheitszeichen für die Wertzuweisung und dann der Wert des Attributes in Anführungszeichen, wobei entweder einfache (') oder doppelte Anführungszeichen (") gewählt werden können. Vor und hinter dem Gleichheitszeichen dürfen Leerzeichen stehen.
Der mögliche Wert eines Attributes und welche Attribute für welches Element notiert werden können, ist in der Spezifikation des jeweiligen XML-Formates festgelegt, sofern es eine solche gibt. Zumindest das Schema einer DTD reicht meist nicht aus, um präzise einzuschränken, wie ein Attributwert aussehen darf, andere Schema-Sprachen haben da etwas bessere Möglichkeiten. Oft reicht aber auch das nicht aus und die erlaubten Werte werden entweder in Prosa festgelegt oder als regulärer Ausdruck oder auch in EBNF-Notation. Im Bedarfsfalle ist dies dann zusätzlich zu einer Validierung anhand eines Schemas zu prüfen.
Beispiel für ein Element mit Attributen und einem weiteren Element als Inhalt, dessen Inhalt wiederum Text ist:
<circle r="10" cx="100" cy="100" fill="red"><title>Roter Knopf</title></circle>
Das Element circle hat also vier Attribute. r hat den Wert '10', cx und cy haben jeweils den Wert '100' und fill den Wert 'red'. Solch ein Element könnte man zum Beispiel in einem Dokument des Formates SVG finden, ein XML-Format für skalierbare Vektorgraphik. Anhand der Namen von Element und Attributen und den Attributwerten ahnt man schon, dass man damit einen roten Kreis vom Radius 10 bekommt, der bei den Koordinaten (100;100) positioniert ist. Der Kreis hat dann offenbar den Titel 'Roter Knopf', der hier als Inhalt und nicht als Attributwert notiert ist. Indessen, in einem anderen XML-Format könnte dieses Beispiel natürlich etwas ganz anderes bedeuten.
Der mögliche Inhalt eines Elementes steht zwischen Anfangs- und Endmarkierung, also zwischen dem '>' der Anfangsmarkierung und dem '<' der Endmarkierung. Was als Inhalt möglich ist, ist im jeweiligen XML-Format für das jeweilige Element festgelegt. Gemäß XML steht folgendes in beliebiger Kombination zur Auswahl: Text, Kommentare, Verarbeitungsanweisungen, Elemente, Entitäten. In nicht leeren Elementen sind Leerzeichen als Inhalt immer möglich, wie diese im Detail behandelt werden, bestimmt das für XML vordefinierte Attribut xml:space, siehe auch den Abschnitt zu vordefinierten Attributen.
Daneben gibt es auch noch eine spezielle Notation für leere Elemente, also solche ohne Inhalt. Solche leeren Elemente können gleichwohl Attribute notiert haben. Für leere Elemente gibt es nur eine Markierung, diese beginnt mit '<' gefolgt vom Elementnamen samt gegebenenfalls vorhandenen Attributen entsprechend der Notation in einer Anfangsmarkierung. Die Markierung eines leeren Elementes endet mit den beiden Zeichen '/>'. Die Notation ist gleichwertig zu der Notation der Anfangsmarkierung direkt gefolgt von der Endmarkierung ohne Zeichen als Inhalt dazwischen. Als Beispiel zweier gleichwertiger Notationen für ein leeres Element circle:
<circle r="10" />
<circle r="10"></circle>
Das ist nicht gleichwertig zu etwa Folgendem:
<circle r="10"> </circle>
<circle r="10">
</circle>
<circle r="10"><title></title></circle>
Bei den letzten drei Beispielen ist das Element circle jeweils nicht leer, beim letzten Beispiel aber das Element title.
Elemente, die in einem anderen Element stehen, nennt man auch dessen Kinder, das Element, in welchem diese Kinder stehen, nennt man Elternelement. Das Elternelement, dessen gegebenenfalls vorhandenenes Elternelement und so weiter nennt man die Vorfahren dieser Kinder. Die Kinder und die Kinder von Kindern nennt man entsprechend auch die Nachfahren. Kinder mit demselben Elternelement nennt man auch Geschwister. Folglich kann das Wurzelelement Kinder haben, aber weder Geschwister noch Vorfahren. Da neben Elementen auch noch Text (und Leerzeichen) oder Kommentar in einem Element notiert sein können, nennt man diese Strukturen insgesamt Knoten, also, sofern man es genau braucht auch Text-Knoten, Kommentar-Knoten und Element-Knoten. Auch die Strukturen im Prolog nennt man jeweils Knoten. In dem Falle wäre der Dokumentknoten der Elternknoten zum Wurzelelement. Der Dokumentknoten hat keinen Knoten als Vorfahren. Dies führt dann letztlich zu einem Dokument-Objekt-Modell (DOM), wo das gesamte Dokument repäsentiert wird durch Objekte oder Knoten. Viele Programme nutzen solch eine DOM-Repräsentation, um ein XML-Dokument zu verarbeiten, entsprechend gibt es vom W3C auch Empfehlungen zum XML-DOM und mit welchen Methoden dieses zu manipulieren ist.
Kurznotation für Elemente:
element ::= EmptyElemTag | STag content ETag
EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
STag ::= '<' Name (S Attribute)* S? '>'
ETag ::= '</' Name S? '>'
content ::= CharData? ((element | Reference | CDSect | PI | Comment) CharData?)*
Attribute ::= Name Eq AttValue
AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'"
Reference ::= EntityRef | CharRef
EntityRef ::= '&' Name ';'
CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
CDSect ::= CDStart CData CDEnd
CDStart ::= '<![CDATA['
CData ::= (Char* - (Char* ']]>' Char*))
CDEnd ::= ']]>'
Der Begriff Name entspricht der Namensproduktion von XML, die in einem späteren Abschnitt noch genau erläutert wird. Sofern noch nicht geschehen, werden die erlaubten Strukturen wie etwa CDSect noch im Text erläutert, ebenso die Verwendung von Attributen (Begriff Attribute) und Entitäten (Begriff EntityRef).
Vordefinierte Attribute
BearbeitenIn XML sind bereits einige Attribute vordefiniert. Diese werden mit dem ebenfalls bereits in XML fest vorgegebenem Präfix 'xml' notiert. Dies erweist sich bei selbst definierten Formaten als großer Vorteil, sind damit doch bereits einige Grundfunktionen verfügbar, für welche ein Programm nur diese vordefinierten Attribute kennen muß und nicht das gesamte, selbstdefinierte Format.
Ein Attribut ist xml:lang zur Kennzeichnung der Sprache, die im jeweiligen Element verwendet wird. Der Wert ist eine mit Leerzeichen separierte Liste von Sprachkennungen wie 'de' (deutsch) oder 'en' (englisch) oder auch 'en-us' (englisch im amerikanischen Dialekt). Siehe auch BCP47.
Ein weiteres ist xml:space mit den Werten 'preserve' oder 'default'. Dies hat Einfluss auf die Interpretation von Leerraum (Leerzeichen, Zeilenumbrüche) im Textinhalt. Bei 'preserve' wird der Leerraum in der Präsentation erhalten. Bei 'default' werden bei der Präsentation mehrere aufeinanderfolgende Leerzeichen oder Zeilenumbrüche zu einem Leerzeichen zusammengefasst. Das ist zumeist die Voreinstellung, sofern ein spezielles Format nichts anderes festlegt. Je nach Format (besonders bei einem graphischen wie SVG) kann es weitere Angaben in der Spezifikation geben, wie mit Textinhalt im Detail umzugehen ist, wie es zum Beispiel mit Hilfe von Glyphen zu einer graphischen Repräsentation des Textes kommt.
xml:base gibt als Wert die Basis-URI an, von der aus Pfadangaben zu absoluten URIs aufgelöst werden sollen. In der Praxis problematisch kann dieses Attribut sein, wenn vom Autor nur Fragmentidentifizierer oder Bezeichner in einem Attribut angegeben werden, welches zu einer absoluten URI aufzulösen ist.
xml:id ist ein dokumentweit eindeutiger Bezeichner oder Fragmentidentifizierer für das Element, entsprechend den Attributen id in (X)HTML oder SVG. Der Wert entspricht einer Zeichenkette gemäß der Namensproduktion (siehe Abschnitt über Wohlgeformtheit). In der Praxis ist zu empfehlen, den Wert immer mit einem Buschstaben [a-z] oder [A-Z] beginnen zu lassen und bei Bedarf weitere Buchstaben, Ziffern, '–' oder '_' oder '.' folgen zu lassen. Leider wurde dieses vordefinierte Attribut erst relativ spät eingeführt, ist also anders als die anderen vordefinierten XML-Attribute nicht bei allen Programmen bekannt, insbesondere bei älteren nicht.
Bei bekannten Formaten wie (X)HTML oder SVG ist hingegen für denselben Zweck ein eigenes Attribut id definiert. In diesen Fällen sollte xml:id nicht verwendet werden sondern das formatspezifische id. Einige Formate oder Formatversionen, etwa SVG Tiny 1.2 erlauben beide und regeln dann, was passiert, wenn beide Attribute bei einem Element, aber mit unterschiedlichen Werten notiert sind, oder noch ärger, wenn derselbe Wert bei unterschiedlichen Elementen auftritt, einmal mit xml:id notiert, einmal mit id. Auch andere Formate können über entsprechende spezielle Regelungen verfügen, um Konflikte zu vermeiden. Primär ist es allerdings immer die Aufgabe des jeweiligen Autors, solche Konflikte von vorneherein zu vermeiden.
Der Vorteil von xml:id gegenüber formatspezifischen Bezeichnern wie id liegt darin, dass die Bezeichner formatübergreifend gelten und auch Fragmente in Formaten referenzierbar sind, ohne dass das genaue Format dem Darstellungsprogramm bekannt sein müsste. Bei einem beliebigen Format ist es also nicht unbedingt notwendig, etwa eine DTD verfügbar zu machen, wenn man xml:id als Fragmentidentifizierer hat, sonst ist es eben notwendig, in der DTD ein Attribut mit dieser Eigenschaft festzulegen und die verarbeitenden Programme müssen validierend sein oder das Format kennen, damit die Funktionalität als Fragmentidentifizierer verfügbar ist.
Beispiel:
<titel xml:lang="de"
xml:space="preserve"
xml:id="Leere">
Über die Leere
und das Nichts
...
</titel>
Entitäten
BearbeitenFür Text oder ganze Elemente oder Gruppen von ganzen Elementen können auch Abkürzungen, sogenannte Entitäten definiert werden. Dies erfolgt entweder in der Dokumenttypdefinition oder der Dokumenttypdeklaration. Diese Entitäten können dann dort notiert werden, wo das stehen darf, was sie abkürzen. Sie werden dann vor einer Verarbeitung oder Präsentation durch das ersetzt, was sie abkürzen.
Insbesondere dürfen Entitäten für Text in Attributwerten notiert werden, sofern das damit Abgekürzte dort stehen darf, aber sie dürfen nicht als Attribut, Attributname selbst in der Anfangsmarkierung stehen.
Entitäten beginnen immer mit dem Zeichen '&' und enden mit dem Zeichen ';'.
Möchte man nun Zeichen, die im Rahmen von XML die erwähnte besondere Bedeutung haben, selbst notierten, so sind dafür speziell von XML vordefinierte Entitäten zu notieren, falls die Zeichen mit der XML-Syntax in Konflikt geraten.
Im Folgenden sind die fünf in XML vordefinierten Entitäten aufgelistet:
Sonderzeichen | Entität |
---|---|
< | <
|
> | >
|
' | '
|
" | "
|
& | &
|
Die Größer- und Kleinerzeichen müssen dabei immer als Entität im Quelltext notiert werden, sollen sie nicht als Elementmarkierungsbegrenzung dienen.
Anführungszeichen im Inhalt sind unproblematisch. Lediglich innerhalb von Attributwerten können sie mit den Anführungszeichen in Konflikt geraten, welche den Attributwert einschließen. Da allerdings dafür die Wahl zwischen einfachen und doppelten Anführungszeichen möglich ist, reduziert sich das Problem bereits. Eine Umschreibung als Entität ist notwendig, wenn man beide Typen notieren möchte oder einheitlich immer dieselben Anführungszeichen für die Attributwerte verwenden will.
Damit hat man sich natürlich das Problem eingehandelt, dass man nun auch immer das Zeichen '&' maskieren muss, um es von der Situation zu unterscheiden, dass eines dieser Zeichen notiert werden soll. Daher gibt es für das Zeichen & ebenfalls eine vordefinierte Entität, die immer stattdessen zu notieren ist.
Je nach Format kann es in der DTD weitere Definitionen für Entitäten geben. Das praktische Problem bei einer externen DTD ist, dass nicht validierende Programme diese nicht nach solchen Definitionen durchsuchen müssen, weswegen die Entitäten im Dokument dann undefiniert sein können. Anders sieht es aus, wenn der Autor des Dokumentes die Definition der Entität in der Dokumenttypdeklaration vornimmt, also im selben Dokument. Solche Entitäten sind auch von nicht validierenden Programmen zu berücksichtigen und sind unbedenklich verwendbar, ebenso wie die vordefinierten XML-Entitäten.
Neben den selbst definierten Entitäten und den von XML vordefinierten Entitäten gibt es auch noch numerische Entitäten für einzelne Zeichen gemäß Unicode. Deren Notation ist ebenfalls vordefiniert und daher immer sicher verfügbar. Offenbar dürfen die eigenen Enitäten nicht mit den vordefinierten Entitäten in Konflikt geraten. Ferner wird mit den Entitäten lediglich das korrekte Zeichen selbst eindeutig identifiziert, ob dies korrekt präsentiert wird, hängt natürlich davon ab, ob das verwendete Darstellungsprogramm dafür einen passenden Schrifttyp hat. So ist es problemlos möglich, altägyptische Schriftzeichen, Schriftzeichen der Maya oder auch Keilschrift per Entität zu notieren, was aber nicht bedeutet, dass diese dann auch bei allen Nutzern darstellbar sein müssen.
Eine numerische Entität beginnt immer mit der Zeichenfolge '&#' und endet mit ';'. Dazwischen steht eine Notation für die Zahl im Unicode, mit welcher das Zeichen repräsentiert wird. Dies kann entweder in hexadezimaler Notation oder in dezimaler Notation erfolgen. Bei dezimaler Notation steht zwischen Anfang und Ende einfach eine dezimale Zahl, also eine Ziffernfolge (Ziffern [0-9]) für die Zahl, die das gewünschte Zeichen repräsentiert. Bei hexadezimaler Notation folgt hinter dem '#' ein 'x' und dann eine hexadezimale Zahl, also eine Ziffernfolge (Ziffern [0-9a-fA-F]) für die Zahl, die das gewünschte Zeichen repräsentiert.
Natürlich lassen sich die Zahlen für verschiedene Zeichen schlecht merken, trotzdem sind solche Entitäten sehr nützlich, selbst wenn die Zeichen in der verwendeten Kodierung durchaus vorhanden sind. Viele in UTF-8 eigentlich direkt verfügbare Zeichen lassen sich etwa nicht direkt über die Tastatur eingeben, sondern man muß sie in Tabellen mit Vorlagen nachschlagen und kopieren. Stattdessen kann man auch 'einfach' die Unicode-Zahl in einer numerischen Entität notieren, was es einem allerdings meist auch nicht erspart, in einer (anderen) Tabelle nachzuschlagen, welche Unicode-Zahl das gewünschte Zeichen repräsentiert. Allerdings kann man so auch Zeichen notieren, die auf dem eigenen Rechner gar nicht repräsentiert werden, somit auch nicht einfach aus einer Vorlage kopieren können.
Die immer mal wieder genannten Leerzeichen entsprechen zum Beispiel folgenden numerischen Entitäten:  , 	, 
, 

Das ist im Wesentlichen das übliche Leerzeichen, welches man bei den üblichen Tastaturen über die breite Taste unten eingeben kann, dazu das Zeichen für Zeilenumbrüche, dazu weitere Zeichen, die einige Betriebssysteme zusätzlich gerne an das Zeichen für einen Zeilenumbruch anhängen.
Interpretierter und nicht interpretierter Inhalt
BearbeitenDer Inhalt von Elementen und Attributen ist aus Sicht von XML interpretierter Inhalt. Das heißt unter anderen, Entitäten werden durch das ersetzt, was sie bezeichnen oder abkürzen und Strukturen wie Elementmarkierungen werden als solche verarbeitet oder interpretiert. Bereits SGML sieht allerdings die Möglichkeit vor, diese Interpretation explizit für einen Bereich in einem Element abzuschalten.
Im Fachjargon wird einfacher Text auch als CDATA bezeichnet, dies ist eine Folge von Zeichen, die zur Kodierung gehören, welche für das Dokument angegeben ist. CDATA als Elementinhalt wird also nicht weiter interpretiert. Ist CDATA allerdings Inhalt eines Attributes, so wird es interpretiert, entsprechend der folgenden Erklärung für PCDATA.
PCDATA ist hingegen interpretierter Text. Außer einer Zeichenfolge wie bei CDATA können als Inhalt auch Entitäten auftreten, die eine Zeichenfolge repräsentieren. Diese Abkürzungen werden dann interpretiert, also die Abkürzung durch das Abgekürzte ersetzt.
Der Autor kann bei Bedarf einen Teil des Inhaltes eines Elementes als CDATA kennzeichnen. Der Bereich beginnt mit
<![CDATA[
und endet mit
]]>
Also zum Beispiel:
<![CDATA[
Irgendein nicht interpretierter Text mit <, >, & etc.
]]>
Folglich darf die schließende Zeichenfolge darin nicht vorkommen. Um diese effektiv zu realisieren, ist zuvor der CDATA-Bereich zu schließen, also etwa so:
<![CDATA[
Wie man
]]]]><![CDATA[>
schreibt...
]]>
Nach dem Wurzelelement
Bearbeiten<!-- Ende des XML-Dokumentes -->
Nachdem ein Wurzelelement geschlossen ist, sind nur Leerzeichen, einfacher Text und Kommentare erlaubt. Dieser Teil trägt nicht zum Inhalt des Dokumentes bei. Abgesehen vom Prolog und den möglichen Kommentaren nach dem Wurzelelement steht also der eigentliche Inhalt des Dokumentes immer in exakt einem Wurzelelement.
Wohlgeformtheit
BearbeitenBereits im Kapitel Syntax wurde auf die Wohlgeformtheit von XML-Dokumenten eingegangen. Nun folgen weitere Regeln der Syntax zu XML.
Im Gegensatz zu Auszeichnungssprachen wie HTML sind in XML Elementenamen nicht vordefiniert und können von den Entwicklern des jeweiligen speziellen XML-Formates frei gewählt werden. Bei der Vergabe von Namen von Elementen und Attributen sind folgende Regeln zu beachten:
- Der Name darf nicht mit 'xml' beginnen (auch nicht, wenn ein oder mehrere Buchstaben großgeschrieben werden).
- Der Doppelpunkt ':' ist reserviert und wird anderweitig verwendet (Damit wird ein Präfix für einen Namensraum vom Namen separiert, siehe auch später das Kapitel dazu, deshalb gehört ':' formal zur Namensproduktion, welche solche Präfixe einschließt, aber nicht zum eigentlichen Element- oder Attributnamen ohne solches Präfix).
- Leerzeichen sind in Namen nicht erlaubt.
Die Namensproduktion (Begriff Name, Nmtoken und Mehrzahl davon) folgt ansonsten formal folgenden Regeln in der Kurznotation:
Name ::= NameStartChar (NameChar)*
Names ::= Name (#x20 Name)*
Nmtoken ::= (NameChar)+
Nmtokens ::= Nmtoken (#x20 Nmtoken)*
NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
Insbesondere ist also folgendes zu beachten, um das noch einmal in Prosaform zu nennen:
Namen von Elementen und Attributen und Groß- und Kleinschreibung
BearbeitenXML unterscheidet zwischen Groß- und Kleinschreibung. Es bestehen Unterschiede zwischen folgenden drei Markierungen:
<TestElement>
<TESTELEMENT>
<Testelement>
XML ist nicht auf ASCII beschränkt
BearbeitenEine weitere Möglichkeit bei der Namensgebung ist die Verwendung von Buchstaben mit Akzent oder Begriffsschriften.
<Gläser>
<España>
<À>
Schließen geöffneter Elemente
BearbeitenWie sich aus dem früheren Abschnitt zur Elementnotation schon implizit ergibt: Jedes geöffnete Element muss wieder geschlossen werden. Die oben geöffneten Elemente werden nun geschlossen:
</À>
</España>
</Gläser>
Offen gelassene Elemente führen bei der Interpretation des XML zum Abbruch der Interpretation. Folgendes ist also falsch:
<nowiki><p>Hier wird ein Text ausgegeben.</nowiki>
Richtig:
<nowiki><p>Hier wird ein Text ausgegeben.</p></nowiki>
Wie erwähnt, für Elemente ohne Inhalt gibt es eine abgekürzte Variante:
<!-- Die lange Variante -->
<Element_ohne_Inhalt></Element_ohne_Inhalt>
<!-- Die gekürzte Variante -->
<Element_ohne_Inhalt />
Korrekte Verschachtelung
BearbeitenWichtig ist die richtige Verschachtelung von Elementen. Verschachtelungen über Kreuz sind nicht gestattet. Der folgende Quelltext ist daher nicht wohlgeformt und fehlerhaft:
<A_Test>
<B_Test>
</A_Test>
</B_Test>
Kind-Elemente müssen zuvor geschlossen werden, bevor das Eltern-Element geschlossen wird:
<A_Test>
<B_Test>
</B_Test>
</A_Test>
Kommentare
BearbeitenKommentare dienen im Quelltext dazu, den darin enthaltenen Text nicht verarbeitet oder präsentiert zu bekommen. Dies kann dazu dienen, den Inhalt zu dokumentieren oder zu erläutern, aber auch testweise oder zeitweise Teile des Dokumentes auszukommentieren, die aktuell nicht zutreffen oder verarbeitet werden sollen.
Kommentare können nahezu im ganzen Dokument verwendet werden. Kommentare können dort notiert werden, wo Inhalt in einem Dokument stehen darf. Kommentare können also insbesondere nicht in Elementmarkierungen stehen. Wo Kommentare im Prolog und nach dem Wurzelelement stehen dürfen, ist bereits zuvor erläutert worden. Kommentare dürfen insbesondere nicht vor einer dem Dokument eventuell voranstehenden XML-Deklaration stehen.
Eingeleitet wird ein Kommentar mit: <!--
.
Abgeschlossen wird es mit -->
.
Der Abschluß erfolgt ohne !.
Innerhalb eines Kommentares darf kein doppelter Bindestrich genutzt werden: --
Daraus ergibt sich, dass Kommentare in XML nicht geschachtelt werden können.
Kurznotation Kommentare:
Comment ::= '<!--' ((Char - '-') | ('-' (Char - '-')))* '-->'
Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
Beispiel 1:
<!-- Dies ist ein Kommentar -->
Kommentare dürfen auch mehrzeilig sein:
Beispiel 2:
<!--
Dieser
Kommentar
ist
mehrzeilig
-->
Ansonsten fehlerhafter Kram ist ebenfalls in einem Kommentar unbedenklich:
Beispiel 3:
<!--
<testElement wasdenn=17>
<em nix><strong></em achtern="true"></strong>
ob < oder > oder &, hier doch egal ...
-->
Dagegen die falschen Beispiele ...
falsches Beispiel 1:
<!-- Dies hat bei flüchtigem Blick die Anmutung eines Kommentars -- ist jedoch nicht wohlgeformt -->
... und ...
falsches Beispiel 2:
<!-- Dies hat bei flüchtigem Blick die Anmutung eines Kommentars, ist jedoch nicht wohlgeformt --!>
falsches Beispiel 3:
<!--
Diese <!-- dumme und fehlerhafte -->
Anmutung
eines
Kommentars
ist
mehrzeilig
-->