我有一个 PHP 脚本试图解析一个巨大的 XML 文件。为此,我使用 XMLReader 库。在解析过程中,我有这个编码错误:
输入不是正确的UTF-8,表示编码!字节:0xA0 0x32 0x36 0x30
我想知道它们是否是一种跳过带有坏字符的记录的方法。
谢谢!
首先,确保您的 XML 文件确实是 UTF-8 编码的。如果不指定编码作为XMLReader::open()
.
如果编码错误是由于 UTF-8 文档中的真正格式错误的字节序列引起的,并且如果您使用的是 PHP > 5.2.0,您可以将LIBXML_NOERROR
和/或(取决于错误级别)LIBXML_NOWARNING
作为位掩码传递给 的第三个参数XMLReader::open()
:
$xml = new XMLReader();
$xml->open('myxml.xml', null, LIBXML_NOERROR | LIBXML_NOWARNING);
如果您使用的是 PHP > 5.1.0,您可以调整libXML
错误处理。
// enable user error handling
libxml_use_internal_errors(true);
/* ... do your XML processing ... */
$errors = libxml_get_errors();
foreach ($errors as $error) {
// handle errors here
}
libxml_clear_errors();
我实际上不知道前面的两个解决方法是否真的允许XMLReader
在发生错误时继续阅读,或者它们是否只抑制错误输出。但值得一试。
回复评论:
libXML
定义XML_PARSE_RECOVER
(1) 但 ext/libxml 不将此常量公开为 PHP 常量。也许可以将整数值传递1
给$options
参数。
$xml = new XMLReader();
$xml->open('myxml.xml', null, LIBXML_NOERROR | LIBXML_NOWARNING | 1);
我会听听 XMLReader 告诉你什么。请记住,许多编码是 ASCII 的超集,因此(例如)UTF-8 和 ISO-8859-1 与前 128 个代码点的 ASCII 相同。很可能您的文件确实编码为 ISO-8859-1,但其中几乎所有字符都来自该字符集的较低 ASCII 一半。在这种情况下,错误将是你让它使用 XML 的默认编码 UTF-8。
在 ISO-8859-1 中,字节序列0xA0 0x32 0x36 0x30
是完全有效的:一个不间断的空格,后跟“2”、“6”、“0”。
$xml = file_get_contents('myxml.xml'); $xml = preg_replace('/[\x0-\x1f\x7f-\x9f]/u', ' ', $xml); //解析下面的$xml
如果您的 XML 文件具有非常简单的结构,您可以“预过滤”它以消除(甚至更好地纠正)错误的记录。
逐条读取并写出过滤后的xml文件,然后处理过滤后的文件。