1

我正在用 python 编写一组工具来从交通模拟软件生成的一些 xml 文件中提取数据。由于生成的文件可能非常大,我使用 xml.parsers.expat 来解析它们。

问题是,当我在 Windows XP 机器上运行我的脚本时,它运行良好,但在家里,在 Ubuntu 10.10 上,在同一个文件上,我收到以下错误:
ExpatError: not well-formed (invalid token): line 1, column 0

该文件最初以 utf-8 编码,并且标签中声明的编码是 ascii,因此尝试将其更改为 utf-8(或 UTF8 或 utf8)但没有成功。由于没有 BOM,我尝试编写它,但仍然没有成功。我还尝试用Unix换行符(CR)替换Windows换行符(CR / LF)。也没有任何成功。

此外,python 的工作版本是 2.7.1,在我的 Ubuntu 机器上是 2.6.6,但不要认为我的问题与此有关:几周前我将工作计算机的 Python 从 2.6 升级到 2.7,没有遇到任何问题。

由于我不是这里的专家,所以我的想法不多了,有什么提示吗?

编辑:经过进一步调查(我现在很头疼,我讨厌与 Unicode 相关的麻烦),看起来问题已通过将系统环境变量 LANG、LC_ALL 和 LANGUAGE 正确设置为(在我的情况下)“fr_FR.utf-8”来解决. 我不明白为什么他们一开始没有,为什么现在,它起作用了......

我感谢你们的手!

4

2 回答 2

3

文档摘录:

xml.parsers.expat.XML_ERROR_INVALID_TOKEN
当输入字节无法正确分配给字符时引发;例如,UTF-8 输入流中的 NUL 字节(值 0)。

ExpatError.lineno
检测到错误的行号。第一行编号为 1。

ExpatError.offset
发生错误的行中的字符偏移量。第一列编号为 0。

以上往往表明您的文件中的第一个字节有问题。

从原始文件开始,该文件适用于 Windows。编辑您的问题以显示执行此操作的结果:

python -c "print repr(open('win_ok_file.xml', 'rb').read(200))"

这将明确显示文件的前 200 个字节中的内容。

还向我们展示您检查过的代码的缩减版本,它可以在 Windows 上运行以克服最初的错误,但在 Linux 上重现该问题。

一些断言,因为它们的价值:

  • “文件最初是用 utf-8 编码的,标签中声明的编码是 ascii”……如果 XML 声明中的编码是“ascii”但文件中有非 ASCII 字符,则符合的解析器应该提出一个例外。你确定你报告的内容吗?

  • XML 文档的默认编码是 UTF-8。也就是说,如果 XML 声明中没有提及编码,或者根本没有 XML 声明,则需要解析器使用 UTF-8 进行解码。

  • 将 UTF-8 BOM 放在开头更有可能是阻碍而不是帮助。

  • XML 标准要求解析器接受CRXML 文档中的有效字节,然后立即假装它不存在(可能在带有 的元素中除外 xmlns:space="preserve")。更改 CR LFLF不是一个好主意。

还有一些问题:“相当大”的文件中有多少字节?您是否考虑过使用iterparse()fromxml.etree.cElementTreelxml

于 2011-02-22T19:12:09.387 回答
3

我遇到了同样的问题,而不是尝试像这样直接解析文件:

document = xmltodict.parse("myfile.xml") # Parse the read document string

我通过一个对象预先打开 xml 文档,间接解析了它,如下所示:

document_file = open("myfile.xml", "r") # Open a file in read-only mode
original_doc = document_file.read() # read the file object
document = xmltodict.parse(original_doc) # Parse the read document string

它奏效了。

于 2014-04-04T13:07:24.053 回答