【问题标题】:XML validation against given DTD in PHP针对 PHP 中给定 DTD 的 XML 验证
【发布时间】:2010-11-19 10:31:30
【问题描述】:

在 PHP 中,我尝试使用我的应用程序指定的 DTD 验证 XML 文档,而不是通过外部获取的 XML 文档。 DOMDocument 类中的 validate 方法似乎只使用 XML 文档本身指定的 DTD 进行验证,所以这不起作用。

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

(这似乎已在Validate XML using a custom DTD in PHP 中提出过,但没有正确答案,因为该解决方案仅依赖于目标 XML 指定的 DTD)

【问题讨论】:

  • 您能否将您的 DTD 添加到目标 XML。使用您的 DTD 创建一个空文档,然后将您的目标 XML 加载到空文档中

标签: php xml validation dtd


【解决方案1】:

注意: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-&gt;loadXML(),因为这只会将DTD 设置为原始的,并且DOMDocument 对象的doctype 属性是只读的,因此您必须复制根节点(包含所有在其中)到一个新的 DOM 文档。

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

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

【讨论】:

    【解决方案2】:

    我认为只有 XSD 才能做到这一点,请参阅:
    http://php.net/manual/en/domdocument.schemavalidate#62032

    【讨论】:

      猜你喜欢
      • 2012-08-21
      • 2011-06-14
      • 2011-01-30
      • 2010-12-28
      • 2015-03-04
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      相关资源
      最近更新 更多