Entities sind im Prinzip Ersetzungen, das heißt, jedes Entity hat
einen Namen und einen Ersetzungstext. Ersetzungstext ist vielleicht nicht
ganz korrekt, denn Entities können auch Bilder, Sounds etc. sein.
Wenn nun irgendwo der Name des Entities (die Entityreferenz) auftaucht,
setzt der Parser dort den Ersetzungstext ein.
Es gibt drei verschiedene Kriterien nach denen Entities gegliedert werden:
allgemeine / Parameterentities, geparste / ungeparste Entities und externe
/ interne Entities.
allgemeine vs Parameterentities
Allgemeine Entities bzw. deren Entityreferenzen können nur im XML-Dokument
auftauchen. Im Gegensatz dazu gibt es Parameterentities nur in der DTD.
Beide Entities werden natürlich wie gewohnt in der DTD deklariert.
geparste vs ungeparste Entities
Referenzen auf geparste Entities werden vom Parser zuerst ersetzt, und
danach analysiert, das heißt auf Markup durchsucht. Ungeparste Entities
werden vom Parser nicht analysiert. Das macht ja bei Bildern o.ä.
auch nicht viel Sinn. Ungeparste Entities müssen an eine externe
Anwendung weitergegeben werden, um verarbeitet zu werden.
externe vs interne Entities
Der Inhalt (Ersetzungstext) eines externes Entity ist nur durch Zugriff
auf eine andere Datei zu bestimmen. Diese Datei kann zum Beispiel ein
Bild, ein Sound oder auch eine XML-Datei sein. Bei einem internen Entity
wird der Inhalt bei der Deklaration bestimmt.
Bei drei Enteilungskriterien gibt es (wer in Mathe aufgepasst hat, sollte
das auch selbst ausrechnen können) acht verschiedene theoretische
Möglichkeiten für Entities. Wenn man darüber nachdenkt,
stellt man aber wahrscheinlich fest, daß nicht alle Kombinationen
sinnvoll sind. Ein internes, ungeparstes Parameterentity zum Beispiel
ist nicht möglich. Insgesamt gibt es in XML fünf verschiedene
Entities: internes geparstes allgemeines Entity, internes geparstes Parameterentity,
externes geparstes allgemeines Entity, externes geparstes Parameterentity
und externes ungeparstes allgemeines Entity.
internes, geparstes, allgemeines Entitiy (a.k.a. internes Entity)
<!ENTITY fhtw "Fachhochschule fuer Technik und Wirtschaft Berlin">
Bei der Deklaration folgt nach dem Schlüsselwort ENTITY
der Name des Entities und dann der Ersetzungstext. Man kann hier schon
gut sehen, daß sich solch ein Entity wunderbar als Abkürzung
eignet. Referenziert wird dieses Entity mit
&fhtw;
Die Referenz besteht also aus dem &, gefolgt vom Namen des
Entities. Abgeschlossen wird das ganze durch das ;. Dort wo die
Entityreferenz auftaucht, wird der Ersetzungstext eingesetzt. Die Entityreferenz
darf an allen Stellen stehen, in denen im XML-Dokument Text erlaubt ist:
<student hochschuhle="&fhtw;">
<uni>&fhtw;</uni>
</student>
Ich geb ja zu, daß dieses Beispiel nicht grade der Weisheit letzter
Schluss ist, aber zur Demonstration war es ausreichend.
Da geparste Entities auch Markup enhalten können (das vom Parser
analysiert wird), wäre auch folgendes denkbar:
<?xml version="1.0">
<!DOCTYPE student [
<!ELEMENT student (uni)>
<!ELEMENT uni (#PCDATA)>
<!ENTITY fhtw "Fachhochschule fuer Technik und Wirtschaft Berlin">
<!ENTITY uni "<uni>&fhtw;</uni>">
]>
<student>
&uni;
</student>
Wie man hier sehen kann, können innerhalb von Entities auch Entitiereferenzen
verwendet werden. Nicht erlaubt sind allerdings rekursive Verwendungen
(das heißt, in einem Entity A, oder einem in A verwendeten Entity,
darf keine Referenz auf A stehen). Außerdem dürfen Tags nicht
in einem Entity beginnen, und in einem anderen enden.
Es gibt fünf vordefinierte interne, allgemeine, geparste Entities:
- ' referenziert ein Apstroph (‚)
- > referenziert ein Größer-als
(>) - < referenziert ein Kleiner-als (<)
- & referenziert ein Kaufmanns-und (&)
- " referenziert ein Anführungszeichen (")
Diese Entities braucht man nicht selbst deklarieren.
internes, geparstes, Parameterentity (a.k.a. internes Parameterentity)
<!ENTITY % headings "H1 | H2 | H3 | H4 | H5 | H6">
Der einzige Unterschied zur Deklaration eines allgemeinen Entities besteht
in dem %. Auch die Entityreferenz verwendet das %:
%headings;
Die Verwendung erfolgt ähnlich wie beim allgemeinen Entity:
<?xml version="1.0">
<!DOCTYPE body [
<!ENTITY % headings "H1|H2|H3|H4|H5|H6">
<!ENTITY % list "UL|OL|DIR|MENU">
<!ELEMENT BODY (%headings;|P|%list;|PRE|HR|IMG)*>
]>
<BODY>
<H1>Überschrift</H1>
</BODY>
externes, geparstes, allgemeines Entity (a.k.a. externes Entity)
<!ENTITY kapitel1 SYSTEM "www.frag-mich-mal.de/kap1.xml">
Das Prinzip ist euch hoffentlich inzwischen klar geworden. Nach dem Namen
des Entities folgt hier das Schlüsselwort SYSTEM und danach
die Angabe wo das externe Entity gefunden werden kann. Auch die Entityreferenz
sollte euich inzwischen bekannt vorkommen (wenn nicht habe ich wohl total
versagt):
&kapitel1;
Wie bei allen geparsten Entities, darf auch das externe Entity Markup
enthalten.
externes, geparstes Parameterentity (a.k.a. externes Parameterentity)
Wenn ihr gut seid, könnt ihr diesen Abschnitt schon schlussfolgern.
Im Prinzip gibt es nichts Neues:
<!ENTITY % buch SYSTEM "www.frag-mich-nicht.de/buch.dtd">
Genau, ihr habts erraten. Die Entityreferenz ist:
%buch;
Diese Art der Entities bringt eine Menge interessanter Möglichkeiten
mit sich. So wird es möglich, die DTD aufzuteilen, und an verschiedenen
Stellen aufzubewahren. Beispielsweise könnte ein Buchladen die DTD
buch.dtd von www.buch.de, die DTD kunde.dtd von www.sonstwo.de, und die
DTD rechnung.dtd von www.rechnungen.org nutzen, und sich damit seine eigenen
DTD’s zusammenbauen. Das bedeutet, daß Teil-DTD’s (eigentlich sind
das natürlich auch vollständige DTD’s) im Internet zugänglich
sein können, und damit der Allgemeinheit zur Verfügung stehen.
Das ist immens wichtig, vor dem Hintergrund, daß man nicht ständig
für jede Kleinigkeit eine neue DTD entwickeln will. Man kann sich
ganze Bibliotheken von DTD’s vorstellen, aus denen man sich die aussucht,
die man braucht.
externes, ungeparstes, allgemeines Entity (a.k.a. ungeparstes Entity)
Das ungeparste Entity weist einige Besonderheiten auf. Schon die Deklaration
unterscheidet sich von dem, was wir bereits kennen:
<!ENTITY bild SYSTEM "/bilder/foto.jpg" NDATA jpeg>
Nach dem Schlüsselwort ENTITY folgt wie gewohnt der Name
des Entities. Dann kommt das Schlüsselwort SYSTEM und die
Angabe wo das Bild zu finden ist. Bis dahin ja nichts Neues. Nun folgt
aber das Schlüsselwort NDATA. Dies sagt dem Parser eigentlich
nur, daß es sich nicht um interpretierbare Daten (im Sinne von XML)
handelt. Das abschließende jpeg ist ein Name (der natürlich
frei vergeben werden kann), der mit dem Namen einer Notation übereinstimmen
muß (was das nun wieder ist, dazu komme ich gleich).
Auch die Entityreferenz wird anders verwendet als bisher. Sie darf nämlich
nur als Attributwert eines Attributes vom Typ Entity auftreten. Ich sehe
förmlich das Nicht-Verstehen in euren Gesichtern, deshalb ein Beispiel.
Ich hoffe das bringt Klarheit:
<!ENTITY passfoto SYSTEM "/bilder/foto.jpg" NDATA jpeg>
<!ELEMENT person EMPTY>
<!ATTLIST person bild ENTITY #REQUIRED>
Im XML-Dokument könnte dann stehen:
<person bild="passfoto"/>
Der Parser wird an dieser Stelle merken, daß bild vom Typ ENTITY
ist und nach einem Entity namens passfoto suchen. In der Deklaration
steht nun wo der Parser das entsprechende Bild finden kann. An dieser
Stelle fragen sich hoffentlich einige von euch (je mehr desto besser),
was denn der Parser nun mit diesem Entity macht. Er kann es ja schlecht
selbst interpretieren (es sei denn, es handelt sich um einen Superparser
der alle möglichen und unmöglichen Datenformate unterstützt).
An dieser Stelle kommen die Notationen ist Spiel, denen ich mich jetzt
widmen möchte.
Notationen
Eine Notation verbindet einen Namen mit einer Anwendung. Beispielsweise
ließe sich der Name jpeg mit der Anwendung bildbetrachter.exe verbinden.
<!NOTATION jpeg SYSTEM "https://www.bilder.de/bildbetrachter.exe">
Der Parser würde also alle externen Entities mit dem Namen jpeg
an die Anwendung bildbetrachter.exe übergeben.
Um das alles noch einaml zusammen zu fassen, hier noch einmal ein kleines
Beispiel zu externen Entities und Notationen:
<?xml version="1.0"?>
<!DOCTYPE person [
<!ENTITY passfoto SYSTEM "/bilder/foto.jpg" NDATA jpeg>
<!NOTATION jpeg SYSTEM "https://www.bilder.de/bildbetrachter.exe">
<!ELEMENT person (name, vorname)>
<!ATTLIST person bild ENTITY #REQUIRED>
<!ELEMENT name (#PCDATA)>
<!ELEMENT vorname (#PCDATA)>
]>
<person bild="passfoto">
<name>Grube</name>
<vorname>Claire</vorname>
</person>