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


readOuterXml(), Input is not proper UTF-8, indicate encoding

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

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

异常消息:

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

我已经确定文件的实际编码是ISO-8859-1,如果我在调用$reader->open()时手动指定它,它将正常工作。

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

我发现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个字符,但它比完全失败的解析要好得多。理想情况下,第三方会正确标记他们的文件。

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

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