2010-10-31 7 views
6

Ich habe ein großes Problem mit der PHP DOMDocument :: validate(), die die DTD systematisch zu fragen scheint.DOMDocument :: validate() Problem

Es ist ein großes Problem, wenn ich z. B. ein XHTML-Dokument as explained here validieren möchte.

Wie w3.org scheint alle Anforderung von einem PHP-Server zu verwerfen, was es unmöglich ist mein Dokument mit dieser Methode zu validieren ...

Gibt es eine Lösung für das?

Dank durch Voraus

[EDIT] Hier einige Präzisierungen:

/var/www/test.php:

<?php 
$implementation = new DOMImplementation(); 

$dtd = $implementation->createDocumentType 
     (
     'html',          // qualifiedName 
     '-//W3C//DTD XHTML 1.0 Transitional//EN', // publicId 
     'http://www.w3.org/TR/xhtml1/DTD/xhtml1-' 
      .'transitional.dtd'      // systemId 
     ); 

$document = $implementation->createDocument('', '', $dtd); 

$document->validate(); 

[http://]127.0.0.1/test.php:

Warning: DOMDocument::validate(http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd): failed to open stream: HTTP request failed! HTTP/1.0 403 Forbidden 
in /var/www/test.php on line 14 

Warning: DOMDocument::validate(): I/O warning : failed to load external entity "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" in /var/www/test.php on line 14 

Warning: DOMDocument::validate(): Could not load the external subset "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" in /var/www/test.php on line 14 

Related Frage:

+0

nicht sicher, was das Problem ist. 'DOMDocument :: validate' validiert das Dokument basierend auf der DTD des geladenen Dokuments. – Gordon

+0

Zum Beispiel, wenn ich diese DTD bereitstellen: http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd, wenn ich DOMDocument :: validate() aufrufen, PHP eine Anfrage senden, um die Datei zu erhalten , aber w3.org antwortet systematisch mit einem 403 Forbidden oder einem 503 Service nicht verfügbar, und PHP sendet mir die Warnung: Fehler beim Laden der externen Entität "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional. dtd " –

+4

Ich sehe, ja. Es ist ein Bug offen dafür: http://bugs.php.net/bug.php?id=48080 – Gordon

Antwort

8

Wie in den Kommentaren darauf hingewiesen, gibt es einen Bug/FeatureRequest für DOMDocument::validate die DTD als String zu akzeptieren:

Sie können die DTD selbst hosten und die systemId entsprechend ändern, oder Sie können einen benutzerdefinierten Stream-Kontext für alle Ladevorgänge bereitstellen, die über libxml ausgeführt werden. Wenn Sie beispielsweise einen UserAgent bereitstellen, wird die Blockierung des W3C umgangen. Sie können den Proxy auch auf diese Weise hinzufügen. Siehe

Beispiel:

$di = new DOMImplementation; 
$dom = $di->createDocument(
    'html', 
    'html', 
    $di->createDocumentType(
     'html', 
     '-//W3C//DTD XHTML 1.0 Transitional//EN', 
     'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd' 
    ) 
); 
$opts = array(
    'http' => array(
     'user_agent' => 'PHP libxml agent', 
    ) 
); 
$context = stream_context_create($opts); 
libxml_set_streams_context($context); 

var_dump($dom->validate()); 

Dies würde Ausgabe

Warning: DOMDocument::validate(): Element html content does not follow the DTD, expecting (head , body), got 

Warning: DOMDocument::validate(): Element html namespace name for default namespace does not match the DTD 

Warning: DOMDocument::validate(): Value for attribute xmlns of html is different from default "http://www.w3.org/1999/xhtml" 

Warning: DOMDocument::validate(): Value for attribute xmlns of html must be "http://www.w3.org/1999/xhtml" 

bool(false) 
+1

Sehr interessante Lösung! Es löst nicht das Problem der systematischen Anforderung ohne Zwischenspeicherung (nicht sehr fair für w3, aber es ist nicht notwendig, jedes Mal, wenn es bedient wird, ein Dokument zu validieren), aber ich kann jetzt meine Dokumente validieren. Danke ^^ –

+1

@GQyy eigentlich, danke für das Stellen der Frage. Das hat mich dazu gebracht, auch heute etwas Neues über DOM zu lernen;) – Gordon