2009-08-13 78 views
10

在PHP中,我试图使用由我的应用程序指定的DTD来验证XML文档 - 而不是从外部提取的XML文档。 DOMDocument类中的validate方法似乎只使用XML文档本身指定的DTD进行验证,所以这不起作用。对PHP中给定的DTD进行XML验证

可以这样做,以及如何或者我必须将我的DTD转换为XML模式,以便我可以使用schemaValidate方法?

(这似乎已在Validate XML using a custom DTD in PHP但没有正确的答案被要求,因为该解决方案唯一依赖于DTD的目标XML speicified)

+4

你能你的DTD添加到目标XML。用你的DTD创建一个空文档,然后将你的目标XML加载到空文档中 – rojoca 2009-08-13 20:43:04

回答

16

注:XML validation可能是受Billion Laughs攻击,以及类似的DoS攻击向量。

这基本上做什么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(); 

?> 

这将验证对bar.dtd文档。

你不能只是叫$new->loadXML(),因为那会刚刚成立的DTD原来的,和DOMDocument对象的doctype属性是只读的,所以你必须复制根节点(与它的一切)到一个新的DOM文档。

我只是刚刚与这个我自己去,所以我不完全确定这是否涵盖了所有内容,但它在我的示例中绝对适用于XML。

当然,快速和肮脏的解决方案是首先将XML作为字符串获取,然后通过自己的DTD搜索并替换原始的DTD,然后加载它。

+0

非常好的例子!非常感谢你。 – Allanrbo 2009-08-16 07:55:07

+0

+1为快速和肮脏的方法 - >搜索和替换。 – 2013-04-05 18:15:15