【问题标题】:readOuterXml(), Input is not proper UTF-8, indicate encodingreadOuterXml(),输入不是正确的UTF-8,表示编码
【发布时间】:2013-12-13 05:38:17
【问题描述】:

我正在使用 XMLReader 来解析来自第三方的大型 XML 文件,文件大小为 1GB+。 XML 文件将编码指定为 UTF8 (<?xml version="1.0" encoding="utf-8" ?>),尽管它不是。

XMLReader 由于未知的编码类型而引发错误,但直到它已经处理了大部分文件。

异常信息:

输入不是正确的UTF-8,表示编码

我已经确定文件的real编码是ISO-8859-1,如果我在调用$reader->open()的时候手动指定这个就可以了。

问题是我的脚本需要从数据库中解析未知文件,所以它需要依赖文件中指定的编码类型。我需要找到一种方法来解析任何文件,无论其编码如何,有什么建议吗?

【问题讨论】:

  • 您必须在解析文件之前确认文件的编码。由于您几乎无法通过将文件读入内存来做到这一点,我想说您要么通过逐行读取并检查每一行来做到这一点,要么使用像iconv 这样的命令行工具来进行检查,而无需一次将其全部读入内存。
  • @deceze:感谢您的建议,我找到了Enca 并将使用它来检测编码。服务器是 Windows,所以我必须自己编译才能测试。

标签: php xml utf-8 character-encoding xmlreader


【解决方案1】:

我发现vim 非常擅长从一种编码转换为另一种编码。

我的诀窍是正常解析文件,当遇到编码错误时,只需用vim重新编码文件并重新开始解析。

这是一个粗略的想法:

$xmlFile = '/path/to/file.xml';

// Parse the file in a loop
while(...)
{

    try
    {
        // Normal parsing logic...

        $reader->readOuterXml();

        //...
    }
    catch(Exception $ex)
    {
        $encoding = getXMLEncoding($xmlFile) ?: 'utf-8';

        exec(sprintf(VIM_PATH . ' -c "set fileencoding=%s" -c "wq" "%s"', $encoding, $xmlFile));

        // File has been re-encoded
        // The real encoding should now match the declared encoding

        // -> Go back to the beginning and parse the file again
    }

}

使用此方法可能会出现 1 或 2 个字符的乱码,但比完全失败的解析要好得多。理想情况下,第 3 方会正确标记他们的文件。

我的系统是 Windows,所以 vim 参数在 Linux 上可能不同(不知道)。

【讨论】:

    【解决方案2】:

    使用simplexml_load_file 解析XML。为了避免编码问题,请在数据上使用utf8_encode

    【讨论】:

    • 1) 一个 1GB 的 XML 文件几乎无法通过一次性加载到内存中来进行解析。 2) 通过utf8_encode 运行整个文件的问题基本相同。 3) OP 不知道文件的编码是什么,所以utf8_encode 在这里几乎不是一揽子解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-29
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 2011-01-31
    • 2019-01-08
    相关资源
    最近更新 更多