3

快速版本:

什么是标准(创新?任何?)捕获和处理 XMLReader 由于格式错误的文件引发的错误的方法 - 特别是未转义的字符。拥有 Tidy(等)并不是一个超级吸引人的选项,有人知道一种简单地跳过有问题的节点并继续前进的方法吗?

描述性版本:

我们都知道,如果格式不正确,它就不是 XML,但说实话——它确实发生了。客户端定期拉入需要读入 mysql 的大量 (50-100MB+) xml 文件。XMLReader 是显而易见的选择,我们编写了一个非常适合我们需要的包装器。

有时,会发生错误并且 read() 无法终止导入 - drat!它几乎总是一个未转义的字符(例如“&”),它会把所有东西都绊倒。在大多数情况下,我们只是让客户致电数据提供者并要求他们修复有缺陷的文件。不幸的是,数据提供者并不总是有义务和/或及时。如果我们能简单地捕捉到错误并直接移动到下一个节点,那就太棒了。

我花了很长时间试图阅读/破解这个,但找不到任何值得细读的东西。我错过了一些明显的东西吗?

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

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

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

我考虑了一些更“创造性”的方法,例如在当前节点的逻辑完成后用 try/catch 嗅探下一个 Read(),但这似乎很笨拙。使用自定义/包装函数模拟 Read() 似乎也有潜力,该函数有助于在节点之间移动并结合错误处理,但我觉得我过于简单化了。

所以总结一下:当 read() 失败时,我怎样才能捕捉到错误并继续前进?我们是否有机会看到即将发生的错误(至少是 XMLReader 会抛出的消息)?

$xml = new XMLReader();
$xml->open($file);

while ($xml->read()) {  

}
4

3 回答 3

3

它是一个 XML 阅读器,它是用来阅读 XML 的。无效的 XML 不是 XML,无法使用 XML 阅读器读取 - 就这么简单。

在导入之前在您的文件上运行xmllint以查看它是否有效,或者做正确的事情并告诉您的数据提供者生成有效的 xml。

于 2011-03-01T08:58:46.110 回答
2

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

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

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

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

关于“继续前进”的部分,恐怕 cweiske 是对的,但无法做到。您可以使用某些工具预先筛选您的 XML 中的错误(甚至使用 XMLReader 解析它们)并尝试更正您发现的错误,即删除/替换无效字符,但是您需要重新开始解析更正的数据。

于 2012-11-28T16:21:22.177 回答
1

我遇到了同样的问题。使用流过滤器,您可以在将 XML 提供给 XMLReader 之前修复它。

这个HTML 到 XML 过滤器就是这样做的。用它作为

$dsn = "php://filter/read=htmltoxml.entities/resource=" . $url;
$xml = XMLReader::open($dsn);
于 2014-06-26T10:54:31.617 回答