Преобразовать в 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'

2 ответов


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

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

как преобразовать ElementTree.Element в строку?

для решения, которое работает как в Python 2 & 3, Используйте .tostring() и .decode().

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() не возвращает строку по умолчанию. Поведение по умолчанию -создать bytestring. Хотя это не было проблемой в Python 2, эти два типа были более различны в Python 3.

в Python 2 вы можете использовать str введите как текстовые, так и двоичные данные. К сожалению, это слияние двух различных концепций может привести к хрупкий код, который иногда работал для любого вида данных, иногда не. [...]

чтобы сделать различие между текстом и двоичными данными более четким и более выраженным, Python 3 [...] сделал текст и двоичные данные различных типов, которые не могут быть слепо смешаны вместе.

источник: перенос кода Python 2 на Python 3

мы можем разрешить эту двусмысленность с помощью decode() чтобы явно преобразовать наш bytestring в обычный текст. Это обеспечивает совместимость с Python 2 и Python 3.

  • Для Python 2 & 3 совместимость: ElementTree.tostring(xml).decode()
  • для совместимости с Python 3:ElementTree.tostring(xml, encoding='unicode', method='xml')

Для справки, я включил сравнение .tostring() результаты между Python 2 и Python 3.

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

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

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

ElementTree.tostring(xml, encoding='utf8', method='xml')
# Python 3: b'<?xml version=\'1.0\' encoding=\'utf8\'?>\n<Person Name="John" />'
# Python 2: <?xml version='1.0' encoding='utf8'?>
#           <Person Name="John" />

спасибо Martijn Peters указал, что str тип данных изменен между Python 2 и 3.


почему бы не использовать str ()?

в большинстве случаев, используя str() будет "cannonical " способ преобразования объекта в строку. К сожалению, используя это с Element возвращает расположение объекта в памяти в виде шестнадцатеричной строки, а не строкового представления данных объекта.

from xml.etree import ElementTree

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