Проверка XML на соответствие заданному DTD в PHP


В PHP я пытаюсь проверить XML-документ с помощью DTD, указанного моим приложением, а не с помощью внешнего XML-документа. Метод validate в классе DOMDocument, похоже, проверяет только с использованием DTD, указанного в самом XML-документе, поэтому это не сработает.

Можно ли это сделать и как, или мне нужно перевести мой DTD в схему XML, чтобы я мог использовать метод schemaValidate?

(похоже, этот вопрос был задан в Проверка XML с использованием пользовательского DTD в PHP, но без правильного ответа, так как решение зависит только от DTD, заданного целевым XML)

Author: Community, 2009-08-13

2 answers

Примечание: Проверка XML может быть подвержена атаке Миллиарда смехов и аналогичным векторам 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 доступно только для чтения, поэтому вам нужно скопировать корневой узел (со всем в нем) в новый DOM документ.

Я сам только что попробовал это сделать, поэтому я не совсем уверен, охватывает ли это все, но это определенно работает для XML в моем примере.

Конечно, быстрым и грязным решением было бы сначала получить XML в виде строки, выполнить поиск и заменить исходный DTD своим собственным DTD, а затем загрузить его.

 16
Author: mercator, 2013-07-29 19:37:08

Я думаю, что это возможно только с помощью XSD, см.:
http://php.net/manual/en/domdocument.schemavalidate#62032

 1
Author: Michał Tatarynowicz, 2011-09-08 18:53:26