Validar XML usando uma DTD personalizada em PHP

Existe uma maneira (sem instalar bibliotecas) de validação de XML usando uma DTD personalizada em PHP?

Dê uma olhada no DOM do PHP , especialmente no DOMDocument :: schemaValidate e DOMDocument :: validate .

O exemplo para DOMDocument :: validate é bastante simples:

Load('book.xml'); if ($dom->validate()) { echo "This document is valid!\n"; } ?> 

Se você tiver o dtd em uma string, você pode validar contra isso usando um wrapper de dados para o dtd:

 $xml = '   Tove Jani Reminder Don\'t forget me this weekend! '; $dtd = '    '; $root = 'note'; $systemId = 'data://text/plain;base64,'.base64_encode($dtd); $old = new DOMDocument; $old->loadXML($xml); $creator = new DOMImplementation; $doctype = $creator->createDocumentType($root, null, $systemId); $new = $creator->createDocument(null, null, $doctype); $new->encoding = "utf-8"; $oldNode = $old->getElementsByTagName($root)->item(0); $newNode = $new->importNode($oldNode, true); $new->appendChild($newNode); if (@$new->validate()) { echo "Valid"; } else { echo "Not valid"; } 

Minha interpretação da questão original é que temos um arquivo XML “on board” que queremos validar contra um arquivo DTD “on board”. Então, aqui é como eu implementaria a idéia “interpolar uma DTD local dentro do elemento DOCTYPE”, expressa nos comentários de Soren e PayamRWD:

 validação de function pública ($ xml_realpath, $ dtd_realpath = null) {
     $ xml_lines = arquivo ($ xml_realpath);
     $ doc = novo DOMDocument;
     se ($ dtd_realpath) {
         // Injectar DTD dentro da linha DOCTYPE:
         $ dtd_lines = arquivo ($ dtd_realpath);
         $ new_lines = array ();
         foreach ($ xml_lines como $ x) {
             // Assume DOCTYPE SYSTEM "blah blah" formato:
             se (preg_match ('/ DOCTYPE /', $ x)) {
                 $ y = preg_replace ('/ SYSTEM "(. *)" /', "[\ n". implodir ("\ n", $ dtd_lines). "\ n]", $ x);
                 $ new_lines [] = $ y;
             } outro {
                 $ new_lines [] = $ x;
             }
         }
         $ doc-> loadXML (implodir ("\ n", $ new_lines));
     } outro {
         $ doc-> loadXML (implodir ("\ n", $ xml_lines));
     }
     // Habilitar o tratamento de erros do usuário
     libxml_use_internal_errors (true);
     se (@ $ doc-> validate ()) {
         eco "Válido! \ n";
     } outro {
         eco "Não válido: \ n";
         $ errors = libxml_get_errors ();
         foreach ($ errors as $ error) {
             print_r ($ error, true);
         }
     }
 }

Observe que o tratamento de erros foi suprimido por brevidade, e pode haver uma maneira melhor / mais geral de lidar com a interpolação. Mas , na verdade, usei esse código com dados reais, e ele funciona com o PHP versão 5.2.17.

Tentando completar a resposta “owenmarshall”:

em xml-validator.php:

adicione html, header, corpo, …

  $dom->Load('template-format.xml');
if ($dom->validate()) {
echo "This document is valid!\n";
} ?>

template-format.xml:

     





]>
    Intereting Posts