XHTML mit PHP DOM validieren
wahsaga
- xml
0 Marc Reichelt
0 Ingo Turski0 molily
1 molily
1 Thomas J.S.1 molily
0 wahsaga
2 Thomas J.S.
hi,
ich versuche folgendes XHTML-Dokument
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
<title>Test</title>
</head>
<body>
<p>Hello, validation!</p>
</body>
</html>
mit Hilfe der DOM Functions von PHP zu validieren (über die Methoden loadHtml() und validate()).
Dabei bekomme ich, zu meiner Überraschung, folgende Meldung:
Warning: DOMDocument::validate(): standalone: body declared in the external subset contains white spaces nodes in [...]
Wenn ich dann die white spaces zwischen body und p eliminiere, wird das Dokument als valide angesehen.
Was habe ich verpasst? In XHTML 1.0 Strict hat mir doch bisher kein Validations-Service white space im Body angemeckert?
Darf ich ein XHTML-Dokument etwa nicht mehr schön lesbar formatieren ...?
Außerdem dauert die Validierung verhältnismäßig lange - logisch, wenn die DTD und zugehörige Ressourcen immer von PHP/meinem Apachen aus dem www geholt werden müssen, zumal auf dieser Ebene vermutlich kein Caching implementiert ist.
Also wollte ich mir die DTD lokal ablegen, und dann im Doctype meines XHTML-Dokumentes darauf verweisen.
Gut, gibt erst mal mecker, weil weitere in der DTD relativ verlinkte Ressourcen dann ebenfalls noch fehlen. Also xhtml-lat1.ent, xhtml-symbol.ent und xhtml-special.ent ebenfalls noch lokal abgelegt, damit "funzt" es erst mal. Gibt es in der DTD noch weitere eingebundene Ressourcen, die ich übersehen habe?
Wie müsste ich jetzt in meiner lokalen Version der DTD den Inhaltstyp von body anpassen, damit white space darin nicht mehr angemeckert wird? Geht es überhaupt?
Oder bleibt mir nur die Möglichkeit, vor dem Validieren white space außerhalb von Tags in Body mittels preg_replace zu entfernen?
gruß,
wahsaga
Hi wahsaga,
Dabei bekomme ich, zu meiner Überraschung, folgende Meldung:
Warning: DOMDocument::validate(): standalone: body declared in the external subset contains white spaces nodes in [...]
Wenn ich dann die white spaces zwischen body und p eliminiere, wird das Dokument als valide angesehen.
Was habe ich verpasst? In XHTML 1.0 Strict hat mir doch bisher kein Validations-Service white space im Body angemeckert?
Darf ich ein XHTML-Dokument etwa nicht mehr schön lesbar formatieren ...?
Ich finde das nicht gerade als Überraschung - alle Inhalte müssen in XHTML Strict in die entsprechenden Elemente (<p>, <div> usw.) gesteckt werden. Wenn nun (gemäß der Definition von HTML/XHTML) da mehrere Whitespace-Zeichen stehen, werden diese als ein Leerzeichen gewertet - es sei denn, man schaltet den XML Parser in den Modus, dass er diese Whitespace-Zeichen ignorieren soll.
Das könnte laut der von dir verlinkten Seite gehen, indem man die Eigenschaft preserveWhiteSpace des DOMDocument-Objekts auf false setzt - denn sie ist standardmäßig auf true.
Also (ungetestet):
$myDOM = new DOMDocument();
$myDOM->preserveWhiteSpace = false;
$myDOM->loadHTML('blalabersülz');
$myDOM->validate();
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hi,
Ich finde das nicht gerade als Überraschung - alle Inhalte müssen in XHTML Strict in die entsprechenden Elemente (<p>, <div> usw.) gesteckt werden.
schon - aber sämtliche Beispiele beim W3C enthalten hier Whitespace und kein mir bekannter Validator hat sich darüber beschwert.
freundliche Grüße
Ingo
Hallo Ingo,
Ich finde das nicht gerade als Überraschung - alle Inhalte müssen in XHTML Strict in die entsprechenden Elemente (<p>, <div> usw.) gesteckt werden.
schon - aber sämtliche Beispiele beim W3C enthalten hier Whitespace und kein mir bekannter Validator hat sich darüber beschwert.
Latürnich. Weil die Validator den Whitespace bewusst übergehen.
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo,
$myDOM->preserveWhiteSpace = false;
Die Einstellung ändern leider nichts daran, das im HTML-Modus deplatzierte Whitespace-Knoten im DOM auftauchen.
Mathias
Hallo molily,
$myDOM->preserveWhiteSpace = false;
Die Einstellung ändern leider nichts daran, das im HTML-Modus deplatzierte Whitespace-Knoten im DOM auftauchen.
Was eigentlich sehr schade ist.
Ich dachte eben daran, ob es eventuell möglich ist, ein DOMDocument-Objekt die HTML-Datei mit loadHTML laden zu lassen, den XML-String mit saveXML zu exportieren und in ein anderes DOMDocument-Objekt mit loadXML wieder zu laden.
Allerdings wird das Dokument auf eine von mir nicht nachvollziehbare Art geändert, sodass der Validator schließlich meckern _muss_.
Auf folgende Art und Weise ist es mir problemlos gelungen, das XHTML-Dokument (als XML) zu laden:
<?php
// Wir geben wirklich alle Meldungen aus
error_reporting(E_ALL);
// DOMDocument erzeugen
$myDOM = new DOMDocument();
// XML-Dokument laden
$myDOM->load('test.html');
// Validator starten
$result = $myDOM->validate();
if ($result) {
echo "XHTML-Dokument konnte erfolgreich geladen werden.\n";
} else {
echo "XHTML-Dokument konnte NICHT geladen werden.\n";
}
?>
Das war aber vermutlich nicht das, was wahsaga unbedingt wollte. Um HTML-Dateien in DOMDocument einzulesen, muss er anscheinend doch vorerst alle Whitespace-Zeichen entfernen.
Grüße
Marc Reichelt || http://www.marcreichelt.de/
Hallo,
mit Hilfe der DOM Functions von PHP zu validieren (über die Methoden loadHtml() und validate()).
Wieso loadHTML?
Du hast XHTML. Wenn das korrektes XHTML ist, kannst und solltest du es als XML verarbeiten - vor allem wenn du es DTD-validieren willst. Wie es scheint, validierst du gerade ein XHTML-Dokument mit einer XML-DTD im Tag-Soup- bzw. SGML-Modus...
Warning: DOMDocument::validate(): standalone: body declared in the external subset contains white spaces nodes in [...]
Ist mir noch nie begegnet. Spezielle Flags sollten nicht nötig sein.
Also wollte ich mir die DTD lokal ablegen, und dann im Doctype meines XHTML-Dokumentes darauf verweisen. (...) Gibt es in der DTD noch weitere eingebundene Ressourcen, die ich übersehen habe?
Soweit ich sehe, nein.
Wie müsste ich jetzt in meiner lokalen Version der DTD den Inhaltstyp von body anpassen
Das sollte unnötig sein.
Oder bleibt mir nur die Möglichkeit, vor dem Validieren white space außerhalb von Tags in Body mittels preg_replace zu entfernen?
Auch das sollte unnötig sein, der Fehler muss woanders liegen.
Mathias
Hallo,
Wie es scheint, validierst du gerade ein XHTML-Dokument mit einer XML-DTD im Tag-Soup- bzw. SGML-Modus...
Spielt eigentlich keine Rolle: ein valides XML-Dokument ist ein valides SGML-Dokument.
Grüße
Thomas
Hallo,
Spielt eigentlich keine Rolle: ein valides XML-Dokument ist ein valides SGML-Dokument.
Ja, »eigentlich«.
Ich habs gerade nochmal probiert: Es liegt tatsächlich an loadXML versus loadHTML. Bei loadHTML kommt »standalone: body declared in the external subset contains white spaces nodes« und das Dokument wird als nicht valide angesehen.
Mathias
hi,
Wieso loadHTML?
Gute Frage - ich hatte das Beispiel auf http://wiki.cc/php/Dom_validation genutzt, und da ich zum Testen das Dokument erst mal aus einem String statt aus einer Datei nehmen wollte, dann statt loadHTMLFile() eben loadHTML() verwendet.
Du hast XHTML. Wenn das korrektes XHTML ist, kannst und solltest du es als XML verarbeiten - vor allem wenn du es DTD-validieren willst.
Ja, einleuchtend - da hab ich das Beispiel zu oberflächlich betrachtet, bzw. zu schnell übernommen.
Und du hast recht, lade und validiere ich das Dokument gleich als XML, ist das Problem entschwunden.
gruß,
wahsaga
Hallo,
mit Hilfe der DOM Functions von PHP zu validieren (über die Methoden loadHtml() und validate()).
Dabei bekomme ich, zu meiner Überraschung, folgende Meldung:
Warning: DOMDocument::validate(): standalone: body declared in the external subset contains white spaces nodes in [...]
Und wenn du es so versuchst?
<?php
$dom = new DOMDocument;
$dom->validateOnParse = true;
$dom->Load('test.html');
?>
ob die Endung .html hier eine Rolle spielt, kann ich dir aber nicht sagen.
Wenn ich dann die white spaces zwischen body und p eliminiere, wird das Dokument als valide angesehen.
Was habe ich verpasst? In XHTML 1.0 Strict hat mir doch bisher kein Validations-Service white space im Body angemeckert?
Darf ich ein XHTML-Dokument etwa nicht mehr schön lesbar formatieren ...?
In der Tat sehr merkwürdig, da libxml2 ja alle Test der "OASIS XML Tests Suite" bestanden haben soll.
Eventuell bekommst du eine besser Fehlermeldung so:
http://at.php.net/libxml_get_errors
Außerdem dauert die Validierung verhältnismäßig lange - logisch, wenn die DTD und zugehörige Ressourcen immer von PHP/meinem Apachen aus dem www geholt werden müssen, zumal auf dieser Ebene vermutlich kein Caching implementiert ist.
Das ist korrekt, die DTD wird aus dem WWW geholt und alles wir sehr langsam (http://www.php.net/manual/en/ref.dom.php#54777)
Also wollte ich mir die DTD lokal ablegen, und dann im Doctype meines XHTML-Dokumentes darauf verweisen.
Das ist schon teilweise richtig, aber wenn du es "ganz" richtig machen willst, erstellst du dazu einen entsprchenden Katalogeintrag. (wirk wie cacheing).
Siehe: http://www.whump.com/moreLikeThis/link/03815
Wie müsste ich jetzt in meiner lokalen Version der DTD den Inhaltstyp von body anpassen, damit white space darin nicht mehr angemeckert wird? Geht es überhaupt?
Gar nicht, denn du müsstest in der DTD
<!ELEMENT body %Block;>
zu
<!ELEMENT body (#PCDATA, %Block;)*> ändern und dann wäre es nicht mehr die richtige XHTML-DTD.
Grüße
Thomas
Hallo,
Und wenn du es so versuchst?
<?php
$dom = new DOMDocument;
$dom->validateOnParse = true;
$dom->Load('test.html');
?>
Das geht - wegen load statt loadHTML/loadHTMLFile.
validateOnParse ist aber nicht so passend, weil es schwieriger ist, an das Resultat der Validierung zu kommen (man müsste libxml_use_internal_errors und libxml_get_errors nutzen).
ob die Endung .html hier eine Rolle spielt, kann ich dir aber nicht sagen.
Die Endung ist egal.
Eventuell bekommst du eine besser Fehlermeldung so:
http://at.php.net/libxml_get_errors
Da bekommt man dieselbe Meldung.
Mathias
hi,
validateOnParse ist aber nicht so passend, weil es schwieriger ist, an das Resultat der Validierung zu kommen (man müsste libxml_use_internal_errors und libxml_get_errors nutzen).
Dass ist aber der schönere Weg, wenn man nicht nur am true/false-Ergebnis interessiert ist - derzeit bekomme ich die Meldungen des Validiervorganges ja lediglich als Warnings rausgeschmissen.
Im produktiven Einsatz wäre es ansprechender, wenn man die Fehler mit obigen Methoden sammelt und dann in "ordentlicher" Form aufbereitet ausgibt.
gruß,
wahsaga
Hallo,
validateOnParse ist aber nicht so passend, weil es schwieriger ist, an das Resultat der Validierung zu kommen (man müsste libxml_use_internal_errors und libxml_get_errors nutzen).
Dass ist aber der schönere Weg
Ja, dieso Methoden musst du sowieso nutzen, um die Meldungen abzufangen.
Ich wollte mich lediglich gegen validateOnParse und für das separate Aufrufen von valide() anssprechen - sonst kannst du Parsing- und Validierungsfehler nicht so einfach trennen. Außerdem kann man erst die Rückgabewerte der load- und valide-Methoden prüfen, dann gegebenenfalls die Fehler mit libxml_get_errors abfragen. Sonst muss man erst in Erfahrung bringen, ob es Fehler gibt, um daraus das Validierungsergebnis zu schließen.
Im produktiven Einsatz wäre es ansprechender, wenn man die Fehler mit obigen Methoden sammelt und dann in "ordentlicher" Form aufbereitet ausgibt.
Japp. Was hältst du eigentlich von Schema-Validierung, wo du schon mit libxml2 arbeitest?
Mathias
hi,
Was hältst du eigentlich von Schema-Validierung, wo du schon mit libxml2 arbeitest?
Ja, werde ich überdenken, hat in der Tat Vorteile.
gruß,
wahsaga
hi,
Japp. Was hältst du eigentlich von Schema-Validierung, wo du schon mit libxml2 arbeitest?
Hm, wenn versuche mein Dokument mittels
DOM->schemaValidate('http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd')
zu validieren, crasht mir jedesmal der Apache [1].
Habe auch versucht, mein Dokument gemäß How to specify an XML Schema um die entsprechenden Attribute im html-Element zu erweitern - kein Änderung.
Liegt's am System - oder muss ich bei der Schema-Validation noch mehr beachten?
gruß,
wahsaga
[1] folgende Kombination:
hi,
Liegt's am System - oder muss ich bei der Schema-Validation noch mehr beachten?
Auf dem Webserver beim Provider klappt es - Konfiguration ähnlich, nur libxml liegt in der etwas älteren Version 2.6.16 vor, und der Apache läuft natürlich unter Linux ...
Na vielleicht ist ein Windows-System wirklich nicht das beste, um sowas zu testen.
gruß,
wahsaga
Hallo,
Hm, wenn versuche mein Dokument mittels
DOM->schemaValidate('http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd')
zu validieren, crasht mir jedesmal der Apache [1].
*gg* Dazu kann ich nichts sagen, unter Windows habe ich damit nie experimentiert.
Auch die Schemata solltest du dir lokal kopieren. Die DTDs brauchst du auch, wenn du Entity-Referenzen benutzt.
Dann zudem:
$dom->resolveExternals = true;
$dom->substituteEntities = true;
Erst wenn das Dokument so geparst wurde, ist die Schema-Validierung möglich (IIRC).
Habe auch versucht, mein Dokument gemäß How to specify an XML Schema um die entsprechenden Attribute im html-Element zu erweitern
Das ist nicht nötig.
Du brauchst höchstens noch das Schema für den xml:-Namespace:
http://www.w3.org/2001/xml.xsd
Das Schema für den XHTML-Namespace nimmt Bezug darauf. Du musst darin noch einen Pfad ändern, damit er die lokale Datei verwendet:
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="xml.xsd"/>
^^^^^^^
Mathias
Hi Matthias,
Dann zudem:
$dom->resolveExternals = true;
$dom->substituteEntities = true;
resolveExternals hatte ich schon gesetzt, substituteEntities aber noch nicht - und mit letzterem "funzt" es dann auch.
Entferne ich es wieder, crasht der Apache mir wieder reproduzierbar.
> Auch die Schemata solltest du dir lokal kopieren. [...]
> Du brauchst höchstens noch das Schema für den xml:-Namespace: [...]
> Das Schema für den XHTML-Namespace nimmt Bezug darauf. Du musst darin noch einen Pfad ändern, damit er die lokale Datei verwendet
Externe Requests macht mein Apache jetzt laut PFW nicht mehr, und nun geht die Schema-Validierung des einfachen Testbeispiels auch in Nullkommanix.
Danke für die Tipps.
gruß,
wahsaga
--
/voodoo.css:
#GeorgeWBush { position:absolute; bottom:-6ft; }
hi,
Also wollte ich mir die DTD lokal ablegen, und dann im Doctype meines XHTML-Dokumentes darauf verweisen.
Das ist schon teilweise richtig, aber wenn du es "ganz" richtig machen willst, erstellst du dazu einen entsprchenden Katalogeintrag. (wirk wie cacheing).
Danke - jetzt muss ich nur noch herausfinden, wie ich das unter Windows nutze :-)
"LibXML looks for a catalog at /etc/xml/catalog."
Und meinen Hoster fragen, ob er so einen Katalogeintrag unter Debian einrichtet.
gruß,
wahsaga