XMLReader(在PHP中)和错误处理

XMLReader (in Php) and Error Handling

快速版本:

捕获和处理XMLReader因文件格式错误(尤其是未转义的字符)而引发的错误的标准方法(创新吗?摆弄Tidy(等等)不是一个吸引人的选择,有人知道一种简单地跳过有问题的节点并继续前进的方法吗?

描述性版本:

我们都知道,如果格式不正确,它就不是XML,但是说实话,它确实会发生。客户端会定期提取大量(50-100MB +)的xml文件,这些文件需要读入mysql。 XMLReader是显而易见的选择,我们编写了一个包装程序,可以很好地满足我们的需求。

有时会发生错误,并且read()无法终止导入-drat!它几乎总是一个未转义的字符(例如"&"),使所有内容崩溃。在大多数情况下,我们只会让客户致电数据提供者,并要求他们修复其有缺陷的文件。不幸的是,数据提供者并不总是义务和/或及时的。如果我们可以简单地捕捉到错误并继续前进到下一个节点,那将是惊人的。

我花了很长时间尝试阅读/破解此书,但找不到值得细读的内容。我是否缺少明显的东西?

这样的问题似乎很有希望,但没有产生任何结果。传递1似乎应该要求Reader恢复,但是我们只是没有看到任何尝试/不同的错误消息等。这是概述此方法的相关代码:

1
$xml->open($file, null, LIBXML_NOERROR | LIBXML_NOWARNING | 1);

我总是可以使用Tidy进行预处理,但是必须有更好的方法。

我已经考虑过其他一些"创造性"的方法,例如在完成当前节点的逻辑后用try / catch嗅探下一个Read(),但这充其量似乎很笨拙。使用自定义/包装函数来模拟Read()似乎也有潜力,该函数可以帮助遍历节点并合并错误处理,但是我觉得我过于简化了。

综上所述:当read()失败时,如何捕捉错误并继续前进?我们是否有机会看到即将发生的错误(至少XMLReader会抛出该消息)?

1
2
3
4
5
6
$xml = new XMLReader();
$xml->open($file);

while ($xml->read()) {  

}


它是XML读取器,是用来读取XML的。无效的XML不是XML,也不能用XML阅读器读取-就这么简单。

在导入之前对文件运行xmllint来查看它是否有效,或者执行正确的操作并告诉数据提供者生成有效的xml。


关于问题的"查看错误"部分:

http://php.net/manual/zh/function.libxml-use-internal-errors.php
当此设置为默认的false值时,将在任何无效的XML上触发PHP警告。
换句话说,您应该已经看过它了:p您只是没有注意,或者实际上没有设置或自定义错误处理程序而向您隐藏PHP警告。

如果使用true调用上述函数,则不会生成警告,而是在该函数返回的内部数组中累积错误:

http://www.php.net/manual/zh/function.libxml-get-errors.php

关于"继续前进"部分,恐怕cweiske是正确的,并且无法完成。您可以使用某些工具(甚至可以使用XMLReader对其进行解析)来预先筛选XML中的错误,并尝试纠正发现的错误,即删除/替换无效字符,但是随后您需要重新启动对已纠正数据的解析。


我遇到了同样的问题。使用流过滤器,可以先将XML修复,然后再将其提供给XMLReader。

这个HTML到XML的过滤器可以做到这一点。用作

1
2
$dsn ="php://filter/read=htmltoxml.entities/resource=" . $url;
$xml = XMLReader::open($dsn);