简体   繁体   English

针对PHP中给定DTD的XML验证

[英]XML validation against given DTD in PHP

In PHP, I am trying to validate an XML document using a DTD specified by my application - not by the externally fetched XML document. 在PHP中,我试图使用我的应用程序指定的DTD来验证XML文档 - 而不是通过外部获取的XML文档。 The validate method in the DOMDocument class seems to only validate using the DTD specified by the XML document itself, so this will not work. DOMDocument类中的validate方法似乎只使用XML文档本身指定的DTD进行验证,因此这不起作用。

Can this be done, and how, or do I have to translate my DTD to an XML schema so I can use the schemaValidate method? 可以这样做,以及如何或者我必须将我的DTD转换为XML模式,以便我可以使用schemaValidate方法?

(this seems to have been asked in Validate XML using a custom DTD in PHP but without correct answer, since the solution only relies on DTD speicified by the target XML) (这似乎是在Validate XML中使用PHP中的自定义DTD但没有正确答案的问题,因为解决方案仅依赖于目标XML指定的DTD)

Note: XML validation could be subject to the Billion Laughs attack, and similar DoS vectors. 注意: XML验证可能受到Billion Laughs攻击以及类似的DoS向量的影响。

This essentially does what rojoca mentioned in his comment: 这基本上就是rojoca在评论中提到的:

<?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 . 这将针对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. 你不能只调用$new->loadXML() ,因为这只会将DTD设置为原始,并且DOMDocument对象的doctype属性是只读的,所以你必须复制根节点(包含所有内容)它)到一个新的DOM文档。

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. 我自己只是对此有所了解,所以我不完全确定这是否涵盖了所有内容,但它绝对适用于我的示例中的XML。

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. 当然,快速而肮脏的解决方案是首先将XML作为字符串获取,使用您自己的DTD搜索并替换原始DTD,然后加载它。

I think that's only possible with XSD, see: 我认为这只适用于XSD,请参阅:
http://php.net/manual/en/domdocument.schemavalidate#62032 http://php.net/manual/en/domdocument.schemavalidate#62032

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM