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'
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')
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()
from xml.etree import ElementTree
xml = ElementTree.Element("Person", Name="John")
xml_str = ElementTree.tostring(xml).decode()
print(xml_str)
Sortie:
<Person Name="John" />
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.
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>