2010-10-31 19 views
6

Ho un grosso problema con PHP DOMDocument :: validate() che sembra chiedere sistematicamente il DTD.DOMDocument :: validate() problem

È un grosso problema quando desidero convalidare, ad esempio, un documento XHTML as explained here.

Come w3.org sembra rifiutare ogni richiesta da un server PHP, è impossibile convalidare il mio documento con questo metodo ...

non v'è alcuna soluzione per questo?

Grazie di anticipo

[EDIT] Ecco alcune precisazioni:

/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 

correlati domanda:

+0

Non so che cosa il problema è. 'DOMDocument :: validate' convalida il documento in base al DTD del documento caricato. – Gordon

+0

Ad esempio, se fornisco questo DTD: http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd, quando chiamo DOMDocument :: validate(), PHP invia una richiesta per ottenere il file , ma w3.org risponde sistematicamente con un servizio 403 Proibito o 503 non disponibile e PHP mi invia l'avviso: impossibile caricare l'entità esterna "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional. dtd " –

+4

Vedo, sì. C'è un bug aperto per questo: http://bugs.php.net/bug.php?id=48080 – Gordon

risposta

8

Come sottolineato nei commenti, c'è un bug/FeatureRequest per DOMDocument::validate per accettare la DTD come una stringa:

È possibile ospitare autonomamente il DTD e modificare di conseguenza il systemId oppure fornire un contesto di flusso personalizzato a qualsiasi caricamento eseguito tramite libxml. Ad esempio, fornire un UserAgent aggirerà il blocco del W3C. Puoi anche aggiungere proxy in questo modo. Vedere

Esempio:

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

Questo sarebbe uscita

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

Soluzione molto interessante! Non risolve il problema della richiesta sistematica senza cache (non molto equo per w3 ma non è necessario convalidare un documento ogni volta che viene servito), ma ora posso convalidare i miei documenti. Grazie ^^ –

+1

@GQyy in realtà, grazie per avermi fatto la domanda. Oggi mi ha fatto imparare qualcosa di nuovo anche sul DOM;) – Gordon