Dr. O. Hoffmann
Mit Eifer hab ich mich der Studien beflissen;
Zwar weiß ich viel, doch möcht ich alles Wissen.
Wagner im Faust von Johann Wolfgang Goethe
Da es sich bei XML um ein Klartextformat handelt, können
mit PHP beliebige XML-Formate sehr einfach dynamisch erzeugt
werden. Um aber sicherzustellen,
daß wirklich beim Nutzer der passende
parser verwendet wird, ist jedoch mit der
header
-Funktion der korrekte header
zu senden.
Bei statischen Dateien sollte das ein aktuell und
korrekt konfigurierter server selbst erledigen. Ist
dies nicht der Fall, der Autor hat aber auf die
Konfiguration des servers keinen Einfluß, so kann
er immer noch statische Dokument durch ein PHP-Skript
per readfile
durchschleusen, welches zuvor den
korrekten header
sendet.
Dabei ist zu bedenken, daß es meist nicht sinnvoll ist, dem Nutzer selbst erfundene Formate anzubieten, die also nicht als Standard spezifiziert sind.
XHTML als XML-Dokument ist hingegen als Standard spezifiziert,
man bekommt allerdings Probleme mit alten Darstellungsprogrammen
wie netscape4 oder msie.
Wenn wir zum Beispiel XHTML-Dokumente nehmen,
zwingt auch erst der korrekte header
das
Darstellungsprogramm des Nutzers dazu, einen XML-parser
zu verwenden und nicht etwa den gewöhnlichen
SGML/HTML-parser.
Dazu ist anzumerken, daß bisherige Darststellungsprogramme für
HTML nie in der Lage waren, HTML im
Sinne von SGML zu interpretieren, sie haben immer nur
Teilbereiche von HTML interpretiert und die Spezifikationen
im Sinne einer SGML nie komplett umgesezt. Das ist etwas
anders bei Programmen, die in der Lage sind, eine spezifizierte und
standardisierte XML zu interpretieren, aufgrund der
einfacheren Sprachkonstruktion ist dies viel einfacher möglich als
eine Interpretation von HTML, welches zudem historisch
schwer belastet ist durch das Problem, daß weltweit über 90%
der HTML-Dokument technisch grob fehlerhaft sind und
trotzdem der Anspruch besteht, daß grob fehlerhafte Dokument sinnvoll
dargestellt werden sollen. Dies ist bei XML deutlich einfacher -
bei groben Syntax- oder Strukturfehlern ist eine Anzeige nicht erforderlich,
stattdessen erscheint eine Fehlermeldung, die dem Autor hilft, brauchbare
Dokumente zu erstellen.
Nun kann HTML an sich ähnlich konsequent und gut strukturiert geschrieben werden wie ein XML-Dokument, weil ein Darstellungsprogramm aber immer auch fehlerhafte Dokumente darstellen wird, entfällt bei HTML selbst eine grobe Qualitätskontrolle durch das Darstellungsprogramm komplett, was bei XML nicht der Fall ist. Somit ist an sich XHTML eine sinnvolle Wahl für qualitativ hochwertige Inhalte, stößt aber auch noch einige Jahre nach der Spezifikation auf das Problem, daß es von einem bekannteren Anbieter von Darstellungsprogrammen boykottiert wird (microsoft heißt die Firma) und bei einer anderen zumindest der Verdacht besteht, daß diese in ihren Suchergebnissen Dokumente benachteiligt, die im Format XHTML vorliegen (Google heißt diese Firma), weswegen es meist sinnvoll ist, zu analysieren, welches Programm solch ein Dokument anfordert und dann per Skript entschieden wird, ob das Dokument korrekt als XHTML gesendet wird oder an solche Programme gezielt fehlerhaft als HTML, obwohl es sich eigentlich um XHTML handelt.
Eine weitere wichtige Anwendung liegt vor, wenn nicht nur ein Namensraum verwendet werden kann, weil eine Kombination von W3C-Standards in einem Dokument notwendig oder sinnvoll erscheint.
Hier ist das Beispiel für ein XHTML-Dokument:
XHTML mit XML per PHP
Funktionieren sollte es mit neueren browsern (kompatibel zu
mozilla5, zum Beispiel auch Konqueror3, Netscape6/7, Opera6/7/8/9).
Wegen fehlender CSS-Dekoration mag das Beispiel etwas trostlos
wirken, für einige andere Effekte, die in XHTML noch funktionieren,
müßte man vielleicht auch noch andere Namensräume
hinzufügen. Das Ganze soll ja aber auch nur das Prinzip
vermitteln und keinen Schönheitspreis gewinnen...
Generell ist die Lage so, daß sich die Darstellungsprogramme nach dem
header
als nach der Notation in der Datei richten, formal
korrekte header
für XHTML sind also etwa:
application/xhtml+xml
application/xml
text/xml
Dazu gibt es auch eine
W3C-Notiz.
application/xhtml+xml ist der eigentlich für
XHTML vorgesehene MIME-Typ!
Das Darstellungsprogramm sollte so wissen, daß er kein (x)-beliebiges
XML bekommt, sondern eben XHTML.
Nun kennen aber einige Darstellungsprogramme diesen
MIME-Typ noch nicht. Aktuell sende ich bei XHTML zunehmend
soweit sinnvoll den richtigen header
:
Üblicher Weise geben Darstellungsprogramme in der Variable HTTP_ACCEPT
an, welche Formate sie verstehen, man kann also vorsichtig formulieren:
<?php # header fuer xhtml senden? # Die Idee ist, wenn der browser ueberhaupt XML kennt, # bekommt er einen richtigen content-type, kennt er # immerhin HTML, bekommt er den, sonst wird geraten, # ob es Netscape4 oder MSIE ist, die bekommen dann # auch text/html, sonst gibt es xhtml. $xhtml=TRUE; $httpheader="Content-type: application/xhtml+xml"; $alterbrowser=0; if(isset($_SERVER['HTTP_ACCEPT'])) { if ( strpos($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml") ) { # nichts zu tun... } else if(strpos($_SERVER["HTTP_ACCEPT"],"application/xml")) { $httpheader="Content-type: application/xml"; $xhtml=TRUE; } else if(strpos($_SERVER["HTTP_ACCEPT"],"text/xml")) { $httpheader="Content-type: text/xml"; $xhtml=TRUE; } else if(strpos($_SERVER["HTTP_ACCEPT"],"text/html")) { $httpheader="Content-type: text/html"; $xhtml=FALSE; } else { # nur wenn gar nichts angegeben ist, raten, ob es # netscape4 oder MSIE ist: $alterbrowser=substr_count(substr($agent, 0, 11), "Mozilla/4."); if ($alterbrowser != "0") { $httpheader="Content-type: text/html"; $xhtml=FALSE; } } header($httpheader); } ?>
Ganz darauf verlassen kann man sich aber auch nicht. Konqueror 3.2/3.3 etwa, kommt mit dem
ersten XHTML-header
zurecht, zeigt das aber nicht unter
HTTP_ACCEPT an. Der bekommt dann aber nach wie vor text/html
vorgesetzt und soll sich nicht beschweren, wenn der nicht behauptet,
XHTML anzeigen zu können, obwohl er es kann. Beim Umrüsten von
HTML auf XHTML
sollte aber unbedingt geprüft werden, ob noch Fehler im Dokument sind, die der
XML-parser
nicht verzeihen wird. Auch CSS-Stilvorlagen muß man gegebenenfalls etwas anpassen, oft
ist es da sinnvoll, Hintergrund-Angaben vom body
-Element ins html
-Element
zu verlagern.
Obiges Beispiel mit dem automatisch generierten header
:
XHTML-header
mit Fallunterscheidung
oder zum Testen mit eigener Auswahl:
XHTML1.1 als application/xhtml+xml
XHTML1.1 als application/xml
XHTML1.1 als text/xml
XHTML1.1 als text/html
XHTML1.1 als text/plain
Spätestens das letzte sollte als XHTML-Quelltext angezeigt werden, sonst arbeitet das
Programm fehlerhaft. Der msie scheint generell Probleme mit XML zu haben, obgleich das
eigentlich einer der ersten war, der überhaupt etwas mit XML anfangen kann, scheint
da aber keine großen Fortschritte gemacht zu haben. Bei meinem Test hat er teilweise
groben Unfug angestellt oder offensichtlich unsinnige Fehlermeldungen ausgespuckt
(angeblich hat er in einer Zeile in der XHTML1.1 DTD des
W3C einen Fehler gefunden. Inzwischen
wurde mir recht überzeugend dargelegt, daß der Fehler nicht in der
DTD ist, sondern beim msie liegt).
Hier ist das Beispiel für eine
SVG:
SVG mit PHP
Funktionieren sollte das mit Programmen, die einen entsprechenden
parser eingebaut haben
(Amaya5 ff, Opera8 ff, Geckos1.8 ff, Konqueror mit KSVG zum Beispiel)
oder wenn ein plugin im Darstellungsprogramm vorhanden ist, der das anzeigt.
Weitere Erläuterungen und Beispiele, bei denen wirklich
SVG mit PHP kombiniert wird, gibt es unter dem Menüpunkt
Vektorgraphik.
Hier ist das Beispiel für eine Datei im Format
MathML:
MathML mit PHP
Das Format wird hier einfach verwendet, um eine Formel für die Weglänge eines
Pfades anzugeben. Mal abgesehen davon, daß Amaya die Zeilenumbrüche ignoriert,
zeigt dieses Programm das Dokument inhaltlich sinnvoll dar. Opera 9.50 (alpha/beta) stellen Teile
richtig dar, besonders sinnvoll sieht das Ergebnis allerdings nicht aus. Obgleich die Geckos angeblich
MathML anzeigen können, ist mir selbst bei diesem einfachen Beispiel keine
Anzeige gelungen; die Geckos versuchen allesamt den Nutzer dazu zu veranlassen, ein anderes
Programm zur Anzeige zu verwenden. Konqueror stellt den Inhalt als Text ohne sinnvolle Formatierung
dar. Wie bereits der Spezifikation zu entnehmen ist, ist es als nicht einfach anzusehen, dies Format mit
einem einfachen Texteditor zu nutzen. In der Regel werden dafür spezielle Programme verwendet oder
etwa LaTex-Dokument in MathML konvertiert. In Planung befindet sich eine
Spezifikation für eine reduzierte Version, welche eine Darstellung des Formates mittels Stilvorlagen
im Format CSS ermöglicht.
Hier ist das Beispiel für eine Datei im Format
SMIL:
SMIL mit PHP
Das Format wird hier einfach verwendet, um drei Bilder hintereinander darzustellen, die
mit PHP dynamisch erzeugt werden. Das Problem von SMIL
scheint zu sein, daß zwar diverse Module davon in anderen Formaten verwendet werden,
es aber kaum ein Programm gibt, welches das Format selbst komplett interpretiert. Eine Anzeige
etwa mit dem Real-Player ist mir nicht gelungen. Diese simple Anwendung läßt sich
jedenfalls auch mit SVG umsetzen, wobei das darin integrierte SMIL-Modul
zur deklarativen Animation verwendet wird, was dann etwa in Opera und dem adobe-plugin nachvollziehbar ist.
Die Dokumentstruktur sieht dann allerdings anders aus.
Hier ist das Beispiel für eine
WML-Ausgabe:
WML mit PHP
Funktionieren sollte das mit browsern, die einen entsprechenden
parser eingebaut haben (Opera4ff zum Beispiel) oder
natürlich mit einem dafür geeigneten Telephon.
Ein Telephon mit solch einer Funktion habe ich
nicht, daher ist mein persönliches Interesse an dem Format sehr
mäßig. Bei W3C werden ohnehin XHTML-Module für
Mobiltelephone angeboten, mag also sein, daß WML über kurz
oder lang auch schon wieder uninteressant zu werden droht.
XML-Dokumente können nun in andere XML-Dokumente
konvertiert werden, etwa in die genannten XHTML, SVG,
WML oder
auch mathML.
Eine solche Konversion vor der Darstellung ist dringend zu empfehlen bei privaten
XML-Dokumenttypen oder bei firmenspezifischen, die allesamt nicht standardisiert sind und
somit von keinem oder bestenfalls einem firmenspezifischen Darstellungsprogramm eine
sinnvolle Anzeige zu erwarten ist.
Diese Konversion findet mit dem XML-Format
XSL
statt. Die Konversion oder Transformation (XSLT) kann nun theoretisch vom Darstellungsprogramm
selbst vorgenommen werden, zum anderen, was derzeit (Januar 2008) aber
vorteilhafter ist, auch auf dem server. Sowohl für den Apachen (HTTP-server)
als auch für PHP gibt es Module, mit denen dieses erledigt werden kann.
Diese enthalten Funktionen, mit denen für das eigene Format ein
Transformationsskript entwickelt werden kann.
Für Näheres möchte ich hier allerdings die jeweilige Anleitung
empfehlen. Die phpinfo
sollte in jedem Falle aufführen, ob solche
Module vorhanden sind oder nicht.
Schauen wir uns den Quelltext der PHP-Datei für
XHTML an:
<?php $content="Content-type: application/xhtml+xml"; header($content); echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?> \n"; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Beispiel xhtml mit xml-parser</title> </head> <body> <h1>Hallo Welt</h1> <h2>Beispiel XHTML mit XML-parser</h2> <p> Das ist also der Text <br /> Mal gucken. </p> <p> <a href="http://validator.w3.org/check/referer"> <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a> </p> </body> </html>
Schauen wir uns den Quelltext der PHP-Datei für
SVG an:
<?php $content="Content-type: image/svg+xml"; header($content); echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?> \n"; ?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="100%" height="100%" viewBox="0 0 5 4" version="1.1" xmlns="http://www.w3.org/2000/svg" xml:lang="de" stroke-width="0.1"> <desc>Vier Rechtecke</desc> <rect x="0.5" y="0.5" width="2" height="1" fill="none" stroke="blue"/> <rect x="0.5" y="2" width="1" height="1.5" fill="none" stroke="red"/> <rect x="3" y="0.5" width="1.5" height="2" fill="none" stroke="green"/> <rect x="2" y="3" width="2.5" height="0.5" fill="none" stroke="yellow"/> <rect x=".01" y=".01" width="4.98" height="3.98" fill="none" stroke="orange" stroke-width=".01" /> </svg>
Schauen wir uns den Quelltext der PHP-Datei für
MathML an:
<?php $content="Content-type: application/mathml+xml"; header($content); echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?> \n"; ?> <!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN" "http://www.w3.org/TR/MathML2/dtd/mathml2.dtd"> <math xmlns="http://www.w3.org/1998/Math/MathML"> <mtext> Sei </mtext> <mspace linebreak="newline" /> <mrow> <mo> ( </mo> <mi> x </mi> <mo> ⁡ </mo> <mrow> <mo> ( </mo> <mi> t </mi> <mo> ) </mo> </mrow> <mo> , </mo> <mi> y </mi> <mo> ⁡ </mo> <mrow> <mo> ( </mo> <mi> t </mi> <mo> ) </mo> </mrow> <mo> ) </mo> </mrow> <mspace linebreak="newline" /> <mtext> ein Pfad in einer Ebene mit einer Parametrisierung mit <mi> t </mi> von <mn>0</mn> bis </mtext> <mspace linebreak="newline" /> <mrow> <mi>L</mi> <mo>=</mo> <msubsup> <mo>∫</mo> <mn>0</mn> <mn>1</mn> </msubsup> <msqrt> <msup> <mrow> <mo>(</mo> <mfrac> <mi>dx</mi> <mi>dt</mi> </mfrac> <mo>)</mo> </mrow> <mn>2</mn> </msup> <mo>+</mo> <msup> <mrow> <mo>(</mo> <mfrac> <mi>dy</mi> <mi>dt</mi> </mfrac> <mo>)</mo> </mrow> <mn>2</mn> </msup> </msqrt> <mi>dt</mi> </mrow> </math>
Schauen wir uns den Quelltext der PHP-Datei für
SMIL an:
<?php $content="Content-type: application/smil+xml"; header($content); echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?> \n"; ?> <!DOCTYPE smil PUBLIC "-//W3C//DTD SMIL 3.0 Language//EN" "http://www.w3.org/2008/SMIL30/SMIL30Language.dtd"> <smil xmlns="http://www.w3.org/ns/SMIL" version="3.0" baseProfile="Language"> <body> <seq begin="3s"> <img src="../labor/erstesbild.php?x=600&y=400&z=1" alt="Bild 1" dur="10s" end="click" /> <img src="../labor/erstesbild.php?x=600&y=400&z=2" alt="Bild 2" dur="10s" end="click" /> <img src="../labor/erstesbild.php?x=600&y=400&z=3" alt="Bild 3" dur="10s" end="click" /> </seq> </body> </smil>
Schauen wir uns den Quelltext der PHP-Datei für
WML an:
<?php $content="Content-type: text/vnd.wap.wml"; header($content); echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?> \n"; ?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml"> <wml> <card id="eins"> <p> wml mit php. </p> <p> <a href="#zwei">gehe zur zweiten Card</a> </p> </card> <card id="zwei"> <p> sollte funzen... </p> <p> <a href="#eins">gehe zur ersten Card</a> </p> </card> </wml>