2009-08-13 8 views
10

W PHP próbuję zweryfikować dokument XML za pomocą DTD określonego przez moją aplikację - a nie przez pobrany zewnętrznie dokument XML. Metoda sprawdzania poprawności w klasie DOMDocument wydaje się sprawdzać tylko za pomocą DTD określonego przez sam dokument XML, więc to nie zadziała.Sprawdzanie poprawności XML w stosunku do podanego DTD w PHP

Czy można to zrobić i jak, czy muszę przetłumaczyć mój DTD na schemat XML, aby móc korzystać z metody schemaValidate?

(to wydaje się, że został poproszony w Validate XML using a custom DTD in PHP ale bez poprawnej odpowiedzi, ponieważ rozwiązanie opiera się tylko na DTD speicified przez XML docelowej)

+4

można dodać do DTD XML docelowej. Stwórz pusty dokument za pomocą DTD, a następnie załaduj docelowy plik XML do pustego dokumentu. – rojoca

Odpowiedz

16

Uwaga: XML validation może być przedmiotem ataku Billion Laughs i podobne wektory DoS .

ten zasadniczo robi to, co rojoca wspomniano w swoim komentarzu:

<?php 

$xml = <<<END 
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE foo SYSTEM "foo.dtd"> 
<foo> 
    <bar>baz</bar> 
</foo> 
END; 

$root = 'foo'; 

$old = new DOMDocument; 
$old->loadXML($xml); 

$creator = new DOMImplementation; 
$doctype = $creator->createDocumentType($root, null, 'bar.dtd'); 
$new = $creator->createDocument(null, null, $doctype); 
$new->encoding = "utf-8"; 

$oldNode = $old->getElementsByTagName($root)->item(0); 
$newNode = $new->importNode($oldNode, true); 
$new->appendChild($newNode); 

$new->validate(); 

?> 

Będzie to potwierdzają dokument przeciwko bar.dtd.

Nie można po prostu wywołać , ponieważ wystarczy ustawić DTD na oryginale, a właściwość DOMDocument dla obiektu doctype jest tylko do odczytu, więc należy skopiować węzeł główny (ze wszystkim). do nowego dokumentu DOM.

Sam sobie z tym poradziłem, więc nie jestem do końca pewien, czy to wszystko obejmuje, ale na pewno działa na XML w moim przykładzie.

Oczywiście, szybkie i brudne rozwiązanie byłoby najpierw uzyskać XML w postaci ciągu, wyszukać i zastąpić oryginalny DTD przez własny DTD, a następnie załadować go.

+0

Bardzo dobry przykład! Dziękuję Ci bardzo. – Allanrbo

+0

+1 dla szybkiej i brudnej metody -> szukaj i zamień. –

Powiązane problemy