python xml fromstring无法解码gbk编码?

时间:2017-07-30 15:39:15

标签: python xml python-2.7 encoding utf-8

我用" gbk"编码xml:

#!/usr/bin/env python
# encoding: utf-8
from xml.etree.ElementTree import Element, SubElement, tostring, fromstring, XML, XMLParser

root = Element('root')
child = SubElement(root, "child")
child.text = u"中文"

result = tostring(root, encoding="gbk")
print(result)
print(result.decode("gbk"))

这将产生如下结果:

b"<?xml version='1.0' encoding='gbk'?>\n<root><child>\xd6\xd0\xce\xc4</child></root>"

所以,我试图像这样解析xml,我这样做:

tree = XML(result.decode("gbk"))
print(tree[0].text)
tree = XML(result.decode("gbk"), parser=XMLParser(encoding="gbk"))
print(tree[0].text)
tree = XML(result.decode("gbk"), parser=XMLParser(encoding="utf-8"))
print(tree[0].text)

我发现所有这些都在python 3.6中有效,但它们都不在python 2.7中,python 2.7中的错误是:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 50-51: ordinal not in range(128)

所以,我有两个问题:

  1. 为什么XMLParser(encoding="gbk") XMLParser(encoding="utf-8")同时在python3.6
  2. 中返回相同的结果
  3. 如何让xml解析器在python2.7中正常工作?(我不认为result.decode('gbk').encode('utf8').replace('GBK', 'utf-8')是个好主意。)

1 个答案:

答案 0 :(得分:-1)

>>> from xml.etree.ElementTree import Element, SubElement, tostring, XML
>>> root = Element("root")
>>> child = SubElement(root, "child")
>>> child.text = u"中文"
>>> result = tostring(root, encoding="utf-8")  # Return str in Py2, Return bytes in Py3
>>> result
'<root><child>\xe4\xb8\xad\xe6\x96\x87</child></root>'
>>> print type(result)
<type 'str'>  # The type str in Py2 is the type bytes in Py3
>>> print result.deocde("utf-8")
<root><child>中文</child></root>
>>> tree = XML(result)
>>> print tree[0].text
中文

对于第二个问题,上面的代码适用于Python 2.7。

更新

我猜你的目的是用gbk编码的字符串构造XML。您可以在Python2中使用lxml或直接使用Python3。

>>> from lxml import etree
>>> root = etree.Element("root")
>>> child = etree.SubElement(root, "child")
>>> child.text = u"中文"
>>> result = etree.tostring(root, encoding="gbk")
>>> result
"<?xml version='1.0' encoding='gbk'?>\n<root><child>\xd6\xd0\xce\xc4</child></root>"
>>> tree = etree.XML(result)
>>> tree[0].text
u'\u4e2d\u6587'