Ответ 1
Примечание: Проверка XML может подпадать под Billion Laughs и аналогичные DoS-векторы.
Это по сути делает то, что ройока упомянул в своем комментарии:
<?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();
?>
Это подтвердит документ с помощью bar.dtd
.
Вы не можете просто вызвать $new->loadXML()
, потому что это просто установит DTD в исходное, а свойство doctype
объекта DOMDocument доступно только для чтения, поэтому вам нужно скопировать корень node ( со всем в нем) к новому документу DOM.
Я только что с этим справился, поэтому я не совсем уверен, что это все покрывает, но это определенно работает для XML в моем примере.
Конечно, быстрое и грязное решение состояло бы в том, чтобы сначала получить XML в виде строки, выполнить поиск и заменить оригинальный DTD своим собственным DTD, а затем загрузить его.