将Python ElementTree转换为字符串


84

每当我致电时ElementTree.tostring(e),都会收到以下错误消息:

AttributeError: 'Element' object has no attribute 'getroot'

还有其他方法可以将ElementTree对象转换为XML字符串吗?

追溯:

Traceback (most recent call last):
  File "Development/Python/REObjectSort/REObjectResolver.py", line 145, in <module>
    cm = integrateDataWithCsv(cm, csvm)
  File "Development/Python/REObjectSort/REObjectResolver.py", line 137, in integrateDataWithCsv
    xmlstr = ElementTree.tostring(et.getroot(),encoding='utf8',method='xml')
AttributeError: 'Element' object has no attribute 'getroot'

Answers:


106

Element对象没有.getroot()方法。挂断该电话,该.tostring()电话将正常工作:

xmlstr = ElementTree.tostring(et, encoding='utf8', method='xml')

6
对于来自搜索引擎的新手来说:当编码为“ utf8”时,它将在<?xml version='1.0' encoding='utf8'?>标头前添加。如果utf-8是,则不包含标题。另外,如果et是ElementTree,则必须通过et.getroot()
野口健二

23
在Python 3中,encoding='utf8'返回字节字符串而不是字符串。我建议tostring(xml, encoding="unicode")改用
Stevoisiak

1
@StevenVascellaro:XML实际上是一种二进制格式,因为数据格式由给定编码的字节组成(在顶部的XML声明中指定,如果缺少,则默认为UTF-8)。在Python 2中,str对象与bytesPython 3是同一类型。输出字节是完全正确的,unicode因为将输出用作本质上是一种增加,因此您可以避免在需要Unicode字符串代替特定用例的情况下进行解码。
马丁·彼得斯

根据help,只会encoding="unicode"返回一个字符串。
cz

45

如何转换ElementTree.Element为字符串?

对于Python 3:

xml_str = ElementTree.tostring(xml, encoding='unicode')

对于Python 2:

xml_str = ElementTree.tostring(xml, encoding='utf-8')

为了与Python 2和3兼容

xml_str = ElementTree.tostring(xml).decode()

用法示例

from xml.etree import ElementTree

xml = ElementTree.Element("Person", Name="John")
xml_str = ElementTree.tostring(xml).decode()
print(xml_str)

输出:

<Person Name="John" />

说明

尽管顾名思义,ElementTree.tostring()它还是在Python 2和3中默认返回一个字节字符串。这在Python 3中是一个问题,它使用Unicode作为字符串

在Python 2中,可以将str类型同时用于文本数据和二进制数据。不幸的是,两个不同概念的融合可能导致脆弱的代码有时对两种数据都起作用,有时却不起作用。[...]

为了使文本和二进制数据之间的区别更加清楚和明显,[Python 3]使文本和二进制数据成为了不同的类型,这些类型不能盲目地混合在一起

来源:将Python 2代码移植到Python 3

如果我们知道使用的是哪个版本的Python,则可以将编码指定为unicodeutf-8。否则,如果我们需要同时与Python 2和3兼容,则可以使用decode()转换为正确的类型。

作为参考,我对.tostring()Python 2和Python 3的结果进行了比较。

ElementTree.tostring(xml)
# Python 3: b'<Person Name="John" />'
# Python 2: <Person Name="John" />

ElementTree.tostring(xml, encoding='unicode')
# Python 3: <Person Name="John" />
# Python 2: LookupError: unknown encoding: unicode

ElementTree.tostring(xml, encoding='utf-8')
# Python 3: b'<Person Name="John" />'
# Python 2: <Person Name="John" />

ElementTree.tostring(xml).decode()
# Python 3: <Person Name="John" />
# Python 2: <Person Name="John" />

感谢Martijn Peters指出str数据类型在Python 2和3之间发生了变化。


为什么不使用str()?

在大多数情况下,使用str()将是将对象转换为字符串的“规范”方法。不幸的是,将此参数与一起使用时Element,会以十六进制字符串而不是对象数据的字符串表示形式返回对象在内存中的位置。

from xml.etree import ElementTree

xml = ElementTree.Element("Person", Name="John")
print(str(xml))  # <Element 'Person' at 0x00497A80>

1
在Python 2中ElementTree.tostring()也会生成一个字节串。该str类型在Python 2中是一个字节字符串(在Python 2str中称为Python 3的类型unicode)。
马丁·彼得斯

1
该功能仅添加到Python 3版本,而没有unicode反向移植到Python2。如果是,则会返回一个字符串。
马丁·彼得斯

0

非拉丁答案扩展

扩展@Stevoisiak的答案并处理非拉丁字符。只有一种方法可以向您显示非拉丁字符。一个方法在Python 3和Python 2上都不同。

输入项

xml = ElementTree.fromstring('<Person Name="크리스" />')
xml = ElementTree.Element("Person", Name="크리스")  # Read Note about Python 2

注:在Python 2,调用时toString(...)码,指派xmlElementTree.Element("Person", Name="크리스")将引发错误...

UnicodeDecodeError: 'ascii' codec can't decode byte 0xed in position 0: ordinal not in range(128)

输出量

ElementTree.tostring(xml)
# Python 3 (크리스): b'<Person Name="&#53356;&#47532;&#49828;" />'
# Python 3 (John): b'<Person Name="John" />'

# Python 2 (크리스): <Person Name="&#53356;&#47532;&#49828;" />
# Python 2 (John): <Person Name="John" />


ElementTree.tostring(xml, encoding='unicode')
# Python 3 (크리스): <Person Name="크리스" />             <-------- Python 3
# Python 3 (John): <Person Name="John" />

# Python 2 (크리스): LookupError: unknown encoding: unicode
# Python 2 (John): LookupError: unknown encoding: unicode

ElementTree.tostring(xml, encoding='utf-8')
# Python 3 (크리스): b'<Person Name="\xed\x81\xac\xeb\xa6\xac\xec\x8a\xa4" />'
# Python 3 (John): b'<Person Name="John" />'

# Python 2 (크리스): <Person Name="크리스" />             <-------- Python 2
# Python 2 (John): <Person Name="John" />

ElementTree.tostring(xml).decode()
# Python 3 (크리스): <Person Name="&#53356;&#47532;&#49828;" />
# Python 3 (John): <Person Name="John" />

# Python 2 (크리스): <Person Name="&#53356;&#47532;&#49828;" />
# Python 2 (John): <Person Name="John" />

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.