Entitäten
Entitäten, Schachtelungen, Namensräume und Dateninseln
Entitäten als Platzhalter
Wir wissen bereits, dass Entitäten Zeichencodes für bestimmte Sonderzeichen sind. Man kann aber auch Entitäten als Variable (Platzhalter) verwenden. Den Entitäten kann man nun Inhalte zuweisen und ausgeben lassen. Am besten wird es deutlich mit dem folgenden Beispiel in dem wir einen Serienbrief erstellen. Zunächst legen wir erstmal die XML- und die DTD-Datei (brief.xml u. brief.dtd) an.
XML: <?xml version="1.0" encoding= "iso-8859-1"?> <!DOCTYPE brief SYSTEM "brief.dtd"> <brief> <an>Peter</an> <betreff>Konzertbesuch</betreff> <text>Hallo Peter, wann treffen wir uns?</text> </brief> DTD: <!ELEMENT brief (an,betreff,text)> <!ELEMENT an (#PCDATA)> <!ELEMENT betreff (#PCDATA)> <!ELEMENT text (#PCDATA)>
Hier wollen wir mit der Entität &name; arbeiten da das Wort Peter zweimal auftaucht. Wichtig hierbei ist dass Entitäten mit & anfangen und mit ; aufhören. Wir müssen jetzt einfach nur die Zeile
Syntax: <!ENTITY entityname "inhalt"> Beispiel: <!ENTITY name "Peter">
anfügen und die Entität &name; überall dort einsetzen wo der Inhalt erscheinen soll. Es ist möglich auf eine externe Datei zuzugreifen, dazu müsste man die eben eingefügte Zeile wie folgt ändern.
Syntax: <!ENTITY entityname SYSTEM "(pfad)datei.end"> Beispiel: <!ENTITY name SYSTEM "name.txt">
Bei der Datei kann es sich um XML- oder TXT-Dateien handeln. Eine andere Gattung der Entities sind die Parameter-Entities. Diese werden verwendet, wenn man mit langen DTDs arbeitet und häufig gleiche Abschnitte erfolgen. Legen wir hier zur Veranschaulichung eine Inventarliste an und speichern sie als inventar.xml ab.
<?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE inventar SYSTEM "inventar.dtd"> <inventar> <tisch marke="Desktop">2</tisch> <stuhl marke="Orkus">3</stuhl> <schrank marke="Troll">1</schrank> <schrank marke="Orkus">1</schrank> <regal marke="Ikea">3</regal> </inventar>
Das Beispiel zeigt, dass wir drei verschiedene Elemente (tisch, schrank, stuhl, regal) verwenden und alle besitzen das Attribut marke. Dieses Attribut soll den Elementen verschiedene Marken (Desktop, Orkus, Troll, Ikea) zuweisen. Die vier Elemente sollen zudem in beliebiger Reihenfolge und beliebig oft auftreten. Umsetzen werden wir es mit einer ODER-Verknüpfung und dem Sternchen-Operator. Parameter-Enties werden nicht, wie normale Entities, mit & ; umschlossen sondern mit % ;. Zudem müssen sie am Anfang der DTD mit der Syntax <!ENTITY % entityname “inhalt”> deklariert werden. Der aufruf der Entität erfolgt dann über %entiyname; . Dem entsprechend müssen wir nun DTD schreiben.
<!ENTITY % attribut "marke (Desktop|Orkus|Troll|Ikea) #REQUIRED"> <!ELEMENT inventar (tisch|stuhl|schrank|regal)*> <!ELEMENT tisch (#PCDATA)> <!ATTLIST tisch %attribut;> <!ELEMENT stuhl (#PCDATA)> <!ATTLIST stuhl %attribut;> <!ELEMENT schrank (#PCDATA)> <!ATTLIST schrank %attribut;> <!ELEMENT regal (#PCDATA)> <!ATTLIST regal %attribut;>
Wir nennen unsere Entität attribut und geben ihr den Inhalt marke (Desktop|Orkus|Troll|Ikea) #REQUIRED. Der Aufruf des Attributs erfolgt an den dafür vorgesehenen Stellen mit %attribut; .
Schachtelungen
Mit Schachtelungen kann man ein XML-Dokument speziell strukturieren. Hierzu werden Gruppen und spezielle Operatoren verwendet. Erstellen wir erst einmal eine XML- und eine DTD-Datei. Diese soll eine Dokumentstruktur anzeigen.
XML: <?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE dokument SYSTEM "dokument.dtd"> <dokument> <abschnitt> <head1>Unterüberschrift</head1> <head2>Hauptüberschrift</head2> <absatz>Text</absatz> <rahmen>Text mit Rahmen</rahmen> </abschnitt> </dokument> DTD: <!ELEMENT dokument (abschnitt+)> <!ELEMENT abschnitt (head1,head2,absatz,rahmen)> <!ELEMENT head1 (#PCDATA)> <!ELEMENT head2 (#PCDATA)> <!ELEMENT absatz (#PCDATA)> <!ELEMENT rahmen (#PCDATA)>
Diese beiden Dateien speichern wir unter dokument.xml und dokument.dtd ab.
Gruppen und Operatoren
Gruppen sind einfache UND- und ODER-Verknüpfungen die mit bestimmten Operatoren erweitert werden können. Schauen wir uns nun die DTD-Datei an. Hier ist auch gleich die erste Gruppierung vorhanden.
Die Zeile <!ELEMENT abschnitt (head1,head2,absatz,rahmen)> beinhaltet eine , die besagt, dass die Elemente in der Klammer die vorgeschriebene Reihenfolge einhalten müssen. Wenn wir die markierte Zeile in (head1|head2|absatz|rahmen) ändern so entsteht eine ODER-Verknüpfung. Bei dieser Verknüpfung darf man nur eines der angegebenen Elemente verwenden. Bei unserem Beispiel würde aber eine Fehlermeldung erscheinen. Kommen wir zu den erwähnten Operatoren. Wir werden sie außerhalb der Klammer schreiben da der Operator für die ganze Gruppe gilt.
Wiederholungsoperator Plus (+)
Also ändern wir unsere Zeil wieder um:
(head1|head2|absatz|rahmen)+
Das Plus bedeutet hier, dass eines der Elemente auf jeden Fall erscheinen muss. Aber es kann eine beliebige Anzahl der Elemente auftreten. Die Zeile können wir auch als UND-Verknüpfung schreiben. Einfach | mit , austauschen.
(head1,head2,absatz,rahmen)+
Hier kannst du die Elemente beliebig oft aufreihen müssen aber in der Reihefolgevorhanden sein.
Operator Sternchen (*)
(head1|head2|absatz|rahmen)+
Mit diesem Operator hat man nun komplett freie Hand. Nun kann man entscheiden in welcher Reihenfolge, wie häufig und ob man die Elemente überhaupt verwenden möchte.
Untergruppen erstellen
Wir schreiben einfach die Zeile in (head1,(head2|absatz),rahmen)+. Hier erstellen wir gerade eine Untergruppen. Mit dieser Änderung erreichen wir dass hinter dem Element head1 entweder head2 oder absatz folgen muss. Danach muss rahmen geschrieben werden. Diese Reihenfolge kann nun beliebig oft wiederholt werden.
Namensräume und Dateninseln
Namensräume
Namensräume (engl. name spaces) sind, wie der Name schon sagt, “Räume für Namen”. Sie dienen dazu Doppeldeutigkeiten zu reparieren. Doppeldeutigkeiten treten dann auf wenn mehrere XML-Dokumente zusammen gefügt werden und diese von verschiedenen Autoren erstellt wurden. Hier kann es dazu kommen, dass die Autoren gleiche Tags verwenden aber dazu verschiedene Bedeutungen assoziieren. Zum Beispiel wird der Tag <produkte></produkte> verwendet. Ein Autor weist diesem Tag einen Artikelnamen zu, ein anderer wiederum die Anzahl. Um dieser Doppeldeutigkeit entgegen zu wirken muss man Namensraum-Präfixe anlegen:
Syntax: <Präfix:tagname></Präfix:tagname> Beispiel: <versand:produkte>Stift</versand:produkte> <lager:produkte>12</lager:produkte>
Der Präfix-Name ist frei wählbar doch es dürfen keine Leer- oder Sonderzeichen enthalten sein; zudem darf der Name nicht mit einer Zahl beginnen.
Deklaration des Namensraumes:
Wir müssen jetzt nur noch den Namensraum festlegen. In unseren Beispiel erzeugen wir nun eine XML-Datei mit zwei Namensräumen.
<?xml version="1.0" encoding="iso-8859-1"?> <sortiment xmlns:versand="http://www.pixelversum.com/versand" xmlns:lager="http://www.pixelversum.com/lager"> <artikel> <versand:produkte>Stift</versand:produkte> <lager:produkte>12</lager:produkte> </artikel> </sortiment>
Wenn wir einen Namensraum deklarieren wollen, müssen wir das Attribut xmlns verwenden. Dieses Attribut steht für XML name space. Nach dem Attribut folgt der Präfix, mit der Zuweisung einer URI (Uniform Ressource Identifier). Für eine URI verwendet man gewöhnlich eine Web-Adresse, da diese einmalig im Netz vorhanden sind. Bei schon festgelegten Namensräumen (z.B. Darstellung von HTML-Tags in XML) ist diese Adresse schon vorgegeben. Deswegen muss man diese verwenden.
HTML-Datei in XML einbinden
Wollen wir doch einfach mal HTML in XML einbinden. Hierzu brauchen wir einen name space für die HTML-Tags. Dieser ist durch die W3C vorgegeben. Der Tag mit der Namensraum-Definition muss folgendermaßen aussehen:
<seite xmlns:html="http://www.w3.org/TR/REC-html40">
Die Skripte mit eingebundenem HTML funktionieren nur mit dieser Namensraumdefinition. So binden wir nun HTML in XML ein:
<?xml version="1.0" encoding="iso-8859-1"?> <seite xmlns:html="http://www.w3.org/TR/REC-html40"> <xmltag>Ich gehöre noch keinem Namensraum an.</xmltag> <html:h1>Ahoi HTML!</html:h1> <html:h2>Eine echte Überschrift 2!</html:h2> <html:marquee>Unfassbar, sogar Lauftext!</html:marquee> <html:p>Ich bin ein Satz in einem HTML-Absatz.</html:p> <html:hr/> </seite>
Wie man sieht kann man sämtliche HTML-Tags verwenden sogar das marque-Tag. Die Tags müssen nach den strengen XML-Regeln geschrieben werden. Unter anderem muss jedes Tag geschlossen werden. HTML-Element wie hr, input oder img müssen zusätzlich mit einem Shlash am Ende geschrieben werden.
Dateninseln in HTML
Jetzt müssen wir auch mal XML in HTML einbinden. Hier verwenden wir sogenannte Dateninseln. Eine Dateninsel beginnt man mit <xml> und beendet diese mit </xml>. Man sollte diesem Tag eine Kennung geben, welche über das Attribut id gelöst wird. Hier nun das Beispiel:
<html> <head> <title>Dateninsel</title> </head> <body> <h1>XML-Dokument in HTML einbetten</h1> <xml id="xmlinsel"> <posten> <name>KnowWare</name> <preis>4</preis> </posten> </xml> <p>Welcome back to HTML!</p> </body> </html>
Leider wird der Internet Explorer und Opera diese Dateninseln nicht unterstützen.