使用非utf-8编码在Python中解析XML

问题描述 投票:2回答:1

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

运行以下代码失败:

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

from lxml import etree

parser = etree.XMLParser(encoding='utf-8')

def convert_xml_to_utf8(xml_str):
    tree = etree.fromstring(xml_str, parser=parser)
    if tree.docinfo.encoding == 'utf-8':
        # already in correct encoding, abort
        return xml_str
    decoded_str = xml_str.decode(tree.docinfo.encoding)
    utf8_encoded_str = decoded_str.encode('utf-8')
    tree = etree.fromstring(utf8_encoded_str)
    tree.docinfo.encoding = 'utf-8'
    return etree.tostring(tree, pretty_print = True, xml_declaration = True, encoding='UTF-8', standalone="yes")


data = '''<?xml version='1.0' encoding='Windows-1255'?><rss version="2.0"><channel ><title ><![CDATA[ynet - חדשות]]></title></channel></rss>'''
print(convert_xml_to_utf8(data))
python xml character-encoding
1个回答
4
投票

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

它很简单:

from xml.etree import ElementTree

#        open in binary mode ↓
with open('/tmp/test.xml', 'rb') as f:
    e = ElementTree.fromstring(f.read())

Etvoilà,e包含您的解析文件,编码已经(大概)由etree根据文件的内部encoding="..."标头正确解释。

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

e = ElementTree.parse('/tmp/test.xml')
© www.soinside.com 2019 - 2024. All rights reserved.