Python lxml:如何处理解析 xml 字符串的编码错误?



我需要解析 xml 数据的帮助。场景如下:

  1. 我有 xml 文件作为字符串加载到 postgresql 数据库中。
  2. 我将它们下载到文本文件中以供进一步分析。每行对应一个 xml 文件。
  3. 字符串具有不同的编码。有些明确指定utf-8,有些则指定 windows-1252。可能还有其他人;有些没有在字符串中指定编码。
  4. 我需要解析这些字符串以获取数据。我发现的最佳方法如下:
encoded_string = bytes(bytearray(xml_data, encoding='utf-8'))
root = etree.fromstring(encoded_string)

当它不起作用时,我收到两种类型的错误消息:

"Extra content at the end of the document, line 1, column x (<string>, line 1)" 
# x varies with string; I think it corresponds to the last character in the line

查看引发异常的行,看起来额外内容错误是由具有windows-1252编码的文件引发的。

我需要能够解析每个字符串,理想情况下,下载后不必以任何方式更改它们。我尝试了以下方法:

  1. 改为应用"windows-1252"作为编码。
  2. 二进制形式读取字符串,然后应用编码
  3. 将字符串读取为二进制并使用etree.fromstring直接转换

最后一次尝试产生了此错误:ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.

我能做什么?我需要能够读取这些字符串,但无法弄清楚如何解析它们。带有窗口编码的 xml 字符串都以<?xml version="1.0" encoding="windows-1252" ?>开头

鉴于表列是文本,所有 XML 内容都以 UTF-8 格式呈现给 python,因此尝试解析冲突的 XML 编码属性会导致问题。

也许尝试从字符串中删除该属性。

我通过删除编码信息、换行符文字和回车符文字来解决这个问题。如果我在 vim 中打开返回错误的文件并运行以下三个命令,则每个字符串都成功解析:

:%s/\r//g
:%s/\n//g
:%s/<?.*?>//g

然后 lxml 解析了字符串而没有问题。

更新:

我有一个更好的解决方案。问题是 和 \r 文本中的 UTF-8 编码字符串我正在复制到文本文件。我只需要用这样的regexp_replace从字符串中删除这些字符:

select regexp_replace(xmlcolumn, '\n|\r', '', 'g') from table;

现在我可以运行以下命令并使用 lxml 读取数据而无需进一步处理:

psql -d database -c "copy (select regexp_replace(xml_column, '\n|\r', '', 'g') from resource ) to stdout" > output.txt

最新更新