Jak przekonwertować ElementTree.Element
na ciąg?
W przypadku Pythona 3:
xml_str = ElementTree.tostring(xml, encoding='unicode')
W przypadku Pythona 2:
xml_str = ElementTree.tostring(xml, encoding='utf-8')
Poniższy kod jest zgodny zarówno z językiem Python 2, jak i 3, ale działa tylko dla znaków łacińskich :
xml_str = ElementTree.tostring(xml).decode()
Przykładowe użycie
from xml.etree import ElementTree
xml = ElementTree.Element("Person", Name="John")
xml_str = ElementTree.tostring(xml).decode()
print(xml_str)
Wynik:
<Person Name="John" />
Wyjaśnienie
Pomimo tego, co sugeruje nazwa, ElementTree.tostring()
domyślnie zwraca bajt testowy w Pythonie 2 i 3. Jest to problem w Pythonie 3, który używa Unicode dla łańcuchów .
W Pythonie 2 możesz użyć str
typu zarówno dla danych tekstowych, jak i binarnych . Niestety, to zbieżność dwóch różnych koncepcji może prowadzić do kruchego kodu, który czasami działał dla obu rodzajów danych, a czasami nie. […]
Aby rozróżnienie między tekstem a danymi binarnymi było wyraźniejsze i wyraźniejsze, [Python 3] uczynił tekst i dane binarne odrębnymi typami, których nie można ślepo mieszać ze sobą .
Źródło: przenoszenie kodu Python 2 na Python 3
Jeśli wiemy, która wersja Pythona jest używana, możemy określić kodowanie jako unicode
lub utf-8
. W przeciwnym razie, jeśli potrzebujemy kompatybilności z Pythonem 2 i 3, możemy użyć decode()
do konwersji na właściwy typ.
Dla porównania zamieściłem porównanie .tostring()
wyników między Pythonem 2 i Pythonem 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" />
Podziękowania dla Martijn Peters za wskazanie, że str
typ danych zmienił się między Pythonem 2 i 3.
Dlaczego nie użyć str ()?
W większości scenariuszy użycie str()
byłoby „ kanonicznym ” sposobem konwersji obiektu na łańcuch. Niestety, użycie tego z Element
zwraca lokalizację obiektu w pamięci jako ciąg szesnastkowy, a nie ciąg znaków reprezentujący dane obiektu.
from xml.etree import ElementTree
xml = ElementTree.Element("Person", Name="John")
print(str(xml))
ElementTree.tostring()
również generuje bytestring.str
Typu jest bytestring Pythona 2 (Python 3'Sstr
typu nazywaunicode
Pythona 2).unicode
wstecz do Pythona 2. Gdyby tak było, otrzymywałbyś z powrotem ciąg znaków.Rozszerzenie odpowiedzi innej niż łacińska
Rozszerzenie do odpowiedzi @ Stevoisiak i radzenie sobie ze znakami spoza alfabetu łacińskiego. Tylko jeden sposób spowoduje wyświetlenie znaków spoza alfabetu łacińskiego. Jedna metoda jest inna w Pythonie 3 i Pythonie 2.
Wejście
xml = ElementTree.fromstring('<Person Name="크리스" />') xml = ElementTree.Element("Person", Name="크리스") # Read Note about Python 2
Wynik
ElementTree.tostring(xml) # Python 3 (크리스): b'<Person Name="크리스" />' # Python 3 (John): b'<Person Name="John" />' # Python 2 (크리스): <Person Name="크리스" /> # Python 2 (John): <Person Name="John" /> ElementTree.tostring(xml, encoding='unicode') # Python 3 (크리스): <Person Name="크리스" /> <-------- Python 3 # Python 3 (John): <Person Name="John" /> # Python 2 (크리스): LookupError: unknown encoding: unicode # Python 2 (John): LookupError: unknown encoding: unicode ElementTree.tostring(xml, encoding='utf-8') # Python 3 (크리스): b'<Person Name="\xed\x81\xac\xeb\xa6\xac\xec\x8a\xa4" />' # Python 3 (John): b'<Person Name="John" />' # Python 2 (크리스): <Person Name="크리스" /> <-------- Python 2 # Python 2 (John): <Person Name="John" /> ElementTree.tostring(xml).decode() # Python 3 (크리스): <Person Name="크리스" /> # Python 3 (John): <Person Name="John" /> # Python 2 (크리스): <Person Name="크리스" /> # Python 2 (John): <Person Name="John" />
źródło
Jeśli potrzebujesz tego tylko do debugowania, aby zobaczyć, jak wygląda XML, zamiast tego
print(xml.etree.ElementTree.tostring(e))
możesz użyć wdump
ten sposób:xml.etree.ElementTree.dump(e)
Działa to zarówno z obiektami jak
Element
iElementTree
jakoe
, więc nie powinno być takiej potrzebygetroot
.Dokumentacja
dump
mówi:źródło