99

每当我打电话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'
4

5 回答 5

137

Element对象没有.getroot()方法。挂断那个电话,.tostring()电话就可以了:

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

.getroot()仅当您有ElementTree实例时才需要使用。

其他注意事项:

  • 这会产生一个bytestring,它在 Python 3 中就是bytes类型。
    如果你必须有一个str对象,你有两个选择:

    1. 从 UTF-8 解码得到的字节值:xmlstr.decode("utf8")

    2. 使用encoding='unicode';这避免了编码/解码周期:

      xmlstr = ElementTree.tostring(et, encoding='unicode', method='xml')
      
  • 如果您想要 UTF-8 编码的字节字符串值或使用 Python 2,请考虑到 ElementTree 没有正确检测utf8为标准 XML 编码,因此它将添加一个<?xml version='1.0' encoding='utf8'?>声明。如果您想防止这种情况,请使用utf-8或(带破折号)。UTF-8不使用时encoding="unicode"添加声明头。

于 2013-03-08T22:22:40.203 回答
60

如何转换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指出strPython 2 和 3 之间的数据类型发生了变化。


为什么不使用 str()?

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

from xml.etree import ElementTree

xml = ElementTree.Element("Person", Name="John")
print(str(xml))  # <Element 'Person' at 0x00497A80>
于 2018-02-07T19:07:25.303 回答
1

非拉丁答案扩展

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

输入

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

注意:在 Python 2 中,调用toString(...)代码时,分配xmlwithElementTree.Element("Person", Name="크리스&quot;)将引发错误...

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="크리스&quot; />             <-------- 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="크리스&quot; />             <-------- 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" />

于 2020-09-17T17:50:42.003 回答
0

如果您只需要它来调试以查看 XML 的外观,那么print(xml.etree.ElementTree.tostring(e))您可以使用dump以下代码:

xml.etree.ElementTree.dump(e)

这适用于ElementElementTree对象 as e,因此不需要getroot.

文档dump说:

xml.etree.ElementTree.dump(elem)

将元素树或元素结构写入sys.stdout. 此功能应仅用于调试。

确切的输出格式取决于实现。在这个版本中,它被编写为一个普通的 XML 文件。

elem是元素树或单个元素。

在 3.8 版更改:该dump()函数现在保留用户指定的属性顺序。

于 2020-12-28T05:05:48.700 回答
0

我在 Python 3.8 中遇到了同样的问题,之前的答案都没有解决它。问题是 ElementTree 既是模块的名称,也是其中的类的名称。使用别名可以清楚地表明:

from xml.etree.ElementTree import ElementTree
import xml.etree.ElementTree as XET
...
ElementTree.tostring(...)  # Attribute-error
XET.tostring(...)          # Works
于 2021-12-04T16:01:50.790 回答