web-dev-qa-db-fra.com

Convertir Python ElementTree en chaîne

Chaque fois que j'appelle ElementTree.tostring(e), le message d'erreur suivant s'affiche:

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

Existe-t-il un autre moyen de convertir un objet ElementTree en chaîne 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'
64
user1732480

Les objets Element n'ont pas de méthode .getroot(). Supprimez cet appel et l'appel .tostring() fonctionne:

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

Comment convertir ElementTree.Element En chaîne?

Pour Python 3:

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

Pour Python 2:

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

Pour la compatibilité avec Python 2 & 3:

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

Exemple d'utilisation

from xml.etree import ElementTree

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

Sortie:

<Person Name="John" />

Explication

Malgré ce que son nom implique, ElementTree.tostring() renvoie une chaîne d'octets par défaut dans Python 2 & 3. Il s'agit d'un problème rencontré dans Python 3. , qui tilise Unicode pour les chaînes .

Dans Python 2, vous pouvez utiliser le type str pour le texte et les données binaires . Malheureusement, cette convergence de deux concepts différents peut conduire à un code fragile qui fonctionne parfois pour l'un ou l'autre type de données, parfois non. [...]

Pour rendre la distinction entre le texte et les données binaires plus claire et plus prononcée, [Python 3] a créé des types distincts de texte et de données binaires qui ne peuvent pas être mélangés à l'aveugle .

Source: Porting Python 2 Code pour Python

Si nous savons quelle version de Python est utilisée, nous pouvons spécifier le codage sous la forme unicode ou utf-8. Sinon, si nous avons besoin de compatibilité avec les deux Python 2 & 3, nous pouvons utiliser decode() pour convertir le type correct.

Pour référence, j'ai inclus une comparaison des résultats de .tostring() entre Python 2 et 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" />

Merci à Martijn Peters pour avoir signalé que le type de données str a changé entre Python 2 et 3.


Pourquoi ne pas utiliser str ()?

Dans la plupart des scénarios, utiliser str() serait le moyen " cannonical " de convertir un objet en chaîne. Malheureusement, utiliser ceci avec Element renvoie l'emplacement de l'objet en mémoire sous forme de chaîne hexagonale, plutôt que de représentation sous forme de chaîne des données de l'objet.

from xml.etree import ElementTree

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