针对PHP中给定DTD的XML验证 [英] XML validation against given DTD in PHP

查看:53
本文介绍了针对PHP中给定DTD的XML验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在PHP中,我尝试使用应用程序指定的DTD而不是外部获取的XML文档来验证XML文档. DOMDocument类中的validate方法似乎仅使用XML文档本身指定的DTD进行验证,因此将无法正常工作.

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

(这似乎已经在中进行了询问,使用自定义来验证XML PHP中的DTD ,但没有正确答案,因为该解决方案仅依赖于目标XML所指定的DTD)

解决方案

注意: XML验证可能会受到 Billion Laughs 攻击以及类似的DoS向量./p>

这基本上是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,然后加载它.

In PHP, I am trying to validate an XML document using a DTD specified by my application - not by the externally fetched XML document. 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.

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?

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

解决方案

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.

这篇关于针对PHP中给定DTD的XML验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆