В PHP я пытаюсь проверить XML-документ с использованием DTD, указанного моим приложением, а не внешним XML-документом. Метод проверки в классе DOMDocument, похоже, проверяет только DTD, указанный самим документом XML, поэтому это не сработает.
Можно ли это сделать и как, или мне нужно перевести мой DTD в схему XML, чтобы я мог использовать метод schemaValidate?
(похоже, это было задано в Validate XML с использованием пользовательского DTD в PHP, но без правильного ответа, поскольку решение зависит только от DTD, заданного целевым XML)
Примечание. Проверка 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 доступно только для чтения, поэтому вам нужно скопировать корневой узел (со всем, что находится в это) к новому документу DOM.
Я только что сделал это с собой, поэтому я не совсем уверен, что это все покрывает, но это определенно работает для XML в моем примере.
Конечно, быстрое и грязное решение состояло бы в том, чтобы сначала получить XML в виде строки, выполнить поиск и заменить исходное DTD собственным DTD, а затем загрузить его.
Я думаю, что это возможно только с XSD, см .:
http://php.net/manual/en/domdocument.schemavalidate#62032