Convertir Python ElementTree a cadena

Cuando llamo a ElementTree.tostring(e) , aparece el siguiente mensaje de error:

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

¿Hay alguna otra manera de convertir un objeto ElementTree en una cadena XML?

Rastrear:

 Traceback (most recent call last): File "Development/Python/REObjectSort/REObjectResolver.py", line 145, in  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' 

Element objetos de Element no tienen ningún método .getroot() . Suelta esa llamada, y la llamada .tostring() funciona:

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

¿Cómo convierto ElementTree.Element a una cadena?

Para una solución que funcione en Python 2 y 3, use .tostring() y .decode() .

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

Ejemplo de uso

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

Salida:

  

Explicación

A pesar de lo que implica el nombre, ElementTree.tostring() no devuelve una cadena de forma predeterminada . El comportamiento por defecto es generar un bytestring . Si bien esto no fue un problema en Python 2, los dos tipos se hicieron más distintos en Python 3.

En Python 2 puede usar el tipo str para texto y datos binarios . Desafortunadamente, esta confluencia de dos conceptos diferentes podría llevar a un código frágil que a veces funcionaba para cualquier tipo de datos, a veces no. […]

Para que la distinción entre texto y datos binarios sea más clara y más pronunciada, Python 3 hizo […] tipos distintos de texto y datos binarios que no se pueden mezclar a ciegas .

Fuente: Portar código de Python 2 a Python 3

Podemos resolver esta ambigüedad mediante el uso de decode() para convertir explícitamente nuestro bytring en texto regular. Esto asegura la compatibilidad con Python 2 y Python 3.

  • Para compatibilidad con Python 2 y 3: ElementTree.tostring(xml).decode()
  • Para compatibilidad con Python 3: ElementTree.tostring(xml, encoding='unicode', method='xml')

Para referencia, he incluido una comparación de los .tostring() de .tostring() entre Python 2 y Python 3.

 ElementTree.tostring(xml).decode() # Python 3:  # Python 2:  ElementTree.tostring(xml, encoding='unicode', method='xml') # Python 3:  # Python 2: LookupError: unknown encoding: unicode ElementTree.tostring(xml, encoding='utf-8', method='xml') # Python 3: b'' # Python 2:  ElementTree.tostring(xml, encoding='utf8', method='xml') # Python 3: b'\n' # Python 2:  #  

Gracias a Martijn Peters por señalar que el tipo de datos str cambió entre Python 2 y 3.


¿Por qué no usar str ()?

En la mayoría de los escenarios, el uso de str() sería la forma ” canónica ” de convertir un objeto en una cadena. Desafortunadamente, usar esto con Element devuelve la ubicación del objeto en la memoria como una cadena hexagonal, en lugar de una representación de cadena de los datos del objeto.

 from xml.etree import ElementTree xml = ElementTree.Element("Person", Name="John") print(str(xml)) #