Подтвердить что ты не робот

Преобразование Python ElementTree в строку

Всякий раз, когда я вызываю ElementTree.tostring(e), появляется следующее сообщение об ошибке:

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

Есть ли другой способ преобразования объекта ElementTree в строку XML?

TraceBack:

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'
4b9b3361

Ответ 1

Element объекты не имеют .getroot() метод. Отбросьте этот вызов, и .tostring():

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

Ответ 2

Как преобразовать 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 используется, мы можем указать кодировку как unicode или utf-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>