2010-10-31 16 views
6

Tengo un gran problema con PHP DOMDocument :: validate() que parece preguntar al DTD sistemáticamente.DOMDocument :: validate() problema

Es un gran problema cuando quiero validar, por ejemplo, un documento XHTML as explained here.

Como w3.org parece rechazar toda solicitud de un servidor PHP, es imposible para validar mi documento con este método ...

¿Hay alguna solución para esto?

Gracias por adelantado

[EDIT] He aquí algunas precisiones:

/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 

Relacionados pregunta:

+0

No estoy seguro que su problema es. 'DOMDocument :: validate' valida el documento basado en la DTD del documento cargado. – Gordon

+0

Por ejemplo, si proporciono este DTD: http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd, cuando llamo a DOMDocument :: validate(), PHP envía una solicitud para obtener el archivo , pero w3.org responde sistemáticamente con un 403 Forbidden o un 503 Service Unavailable, y PHP me envía la advertencia: no se pudo cargar la entidad externa "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional. dtd " –

+4

Ya veo, sí. Hay un error abierto: http://bugs.php.net/bug.php?id=48080 – Gordon

Respuesta

8

Como señaló en los comentarios, hay un error/FeatureRequest para DOMDocument::validate para aceptar la DTD como una cadena:

Puede alojar el DTD usted mismo y cambiar el systemId en consecuencia o puede proporcionar un contexto de flujo personalizado para cualquier carga realizada a través de libxml. Por ejemplo, proporcionar un UserAgent sorteará el bloqueo del W3C. También podría agregar un proxy de esta manera. Ver

Ejemplo:

$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()); 

Esto haría salida

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

¡Solución muy interesante! No resuelve el problema de la solicitud sistemática sin almacenamiento en caché (no es muy justo para w3, pero no es necesario validar un documento cada vez que se sirve), pero ahora puedo validar mis documentos. Gracias ^^ –

+1

@GQyy en realidad, gracias por hacer la pregunta. Me hizo aprender algo nuevo sobre DOM hoy también;) – Gordon