Convertir Python ElementTree en chaîne
chaque fois que j'appelle ElementTree.tostring(e)
, je reçois le message d'erreur suivant:
AttributeError: 'Element' object has no attribute 'getroot'
y a-t-il une autre façon 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'
2 réponses
Element
les objets n'ont pas de méthode .getroot()
. Lâchez cet appel, et le .tostring()
l'appel fonctionne:
xmlstr = ElementTree.tostring(et, encoding='utf8', method='xml')
comment convertir ElementTree.Element
en chaîne de caractères?
pour une solution qui fonctionne à la fois en Python 2 et 3, Utilisez .tostring()
et .decode()
.
xml_str = ElementTree.tostring(xml).decode()
exemple d'usage
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 la nom implique, ElementTree.tostring()
ne renvoie pas une chaîne de caractères par défaut . Le comportement par défaut est de générer un bytestring . Bien que ce n'était pas un problème en Python 2, Les deux types ont été rendus plus distincts en Python 3.
en Python 2, Vous pouvez utiliser le type
str
pour le texte et les données binaires . Malheureusement, cette confluence de deux concepts pourrait conduire à code fragile qui a parfois fonctionné pour l'un ou l'autre type de données, parfois pas. [...]pour rendre la distinction entre texte et données binaires plus claire et plus prononcée, Python 3 [...] fait de types de texte et de données binaires distincts qui ne peuvent pas être mélangés aveuglément ensemble .
Source: porter le Code Python 2 en Python 3
nous pouvons résoudre cette ambiguïté en utilisant decode()
pour convertir explicitement notre bytestring en texte régulier. Cela garantit la compatibilité avec Python 2 et Python 3.
- pour compatibilité Python 2 & 3:
ElementTree.tostring(xml).decode()
- pour compatibilité Python 3:
ElementTree.tostring(xml, encoding='unicode', method='xml')
pour référence, j'ai inclus un comparaison des résultats .tostring()
entre Python 2 et 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" />
merci à Martijn Peters pour avoir souligné 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, en utilisant str()
serait le " cannonique " façon de convertir un objet pour une chaîne de caractères. Malheureusement, en utilisant ceci avec Element
renvoie l'emplacement de l'objet dans la mémoire comme un hexstring, plutôt qu'une représentation de chaîne de caractères des données de l'objet.
from xml.etree import ElementTree
xml = ElementTree.Element("Person", Name="John")
print(str(xml)) # <Element 'Person' at 0x00497A80>