XML validation against given DTD in PHP

廉价感情. 提交于 2019-11-30 05:10:48
mercator

Note: XML validation could be subject to the Billion Laughs attack, and similar DoS vectors.

This essentially does what rojoca mentioned in his comment:

<?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();

?>

This will validate the document against the bar.dtd.

You can't just call $new->loadXML(), because that would just set the DTD to the original, and the doctype property of a DOMDocument object is read-only, so you have to copy the root node (with everything in it) to a new DOM document.

I only just had a go with this myself, so I'm not entirely sure if this covers everything, but it definitely works for the XML in my example.

Of course, the quick-and-dirty solution would be to first get the XML as a string, search and replace the original DTD by your own DTD and then load it.

I think that's only possible with XSD, see:
http://php.net/manual/en/domdocument.schemavalidate#62032

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!