在 Python 中使用 utf-8 以外的编码解析 XML

rub*_*bmz 4 python xml character-encoding

关于如何在 python 中解析包含:encoding=\'Windows-1255\' 的 xml 的任何线索?\n至少 lxml.etree 解析器在存在“编码”时甚至不会查看字符串XML 标头中的标记不是“utf-8”或“ASCII”。

\n\n

运行以下代码失败并显示:

\n\n

ValueError:不支持带有编码声明的 Unicode 字符串。请使用没有声明的字节输入或 XML 片段。\n

\n\n
from lxml import etree\n\nparser = etree.XMLParser(encoding=\'utf-8\')\n\ndef convert_xml_to_utf8(xml_str):\n    tree = etree.fromstring(xml_str, parser=parser)\n    if tree.docinfo.encoding == \'utf-8\':\n        # already in correct encoding, abort\n        return xml_str\n    decoded_str = xml_str.decode(tree.docinfo.encoding)\n    utf8_encoded_str = decoded_str.encode(\'utf-8\')\n    tree = etree.fromstring(utf8_encoded_str)\n    tree.docinfo.encoding = \'utf-8\'\n    return etree.tostring(tree, pretty_print = True, xml_declaration = True, encoding=\'UTF-8\', standalone="yes")\n\n\ndata = \'\'\'<?xml version=\'1.0\' encoding=\'Windows-1255\'?><rss version="2.0"><channel ><title ><![CDATA[ynet - \xd7\x97\xd7\x93\xd7\xa9\xd7\x95\xd7\xaa]]></title></channel></rss>\'\'\'\nprint(convert_xml_to_utf8(data))\n
Run Code Online (Sandbox Code Playgroud)\n

dec*_*eze 7

data是一个 unicode str。该错误表示encoding="..."不支持还包含声明的内容,因为str据说 a 已经从其编码中解码,因此它还包含编码声明是不明确/无意义的。它告诉您使用 abytes代替,例如data = b\'<...>\'。大概您应该以二进制模式打开一个文件,从那里读取数据并让etree处理encoding="...", 而不是在代码中使用字符串文字,这使编码情况进一步复杂化。

\n\n

就这么简单:

\n\n
from xml.etree import ElementTree\n\n#        open in binary mode \xe2\x86\x93\nwith open(\'/tmp/test.xml\', \'rb\') as f:\n    e = ElementTree.fromstring(f.read())\n
Run Code Online (Sandbox Code Playgroud)\n\n

et voil\xc3\xa0,e包含已解析的文件,其编码已(大概)根据etree文件的内部正确解释encoding="..."标头正确解释。

\n\n

ElementTree事实上有一个快捷方法:

\n\n
e = ElementTree.parse(\'/tmp/test.xml\')\n
Run Code Online (Sandbox Code Playgroud)\n

  • 是的。如果将“bytes”(而不是“str”)提供给解析器,它将解析 XML 编码声明并根据该声明将“bytes”解码为“str”。在上面的示例中,“f.read()”生成“字节”,但该值可以来自任何地方。 (2认同)