Mam program, który czyta dokument xml z gniazda. Mam dokument XML przechowywany w łańcuchu, który chciałbym przekonwertować bezpośrednio do słownika Pythona, tak samo jak jest to zrobione w simplejson
bibliotece Django .
Weźmy jako przykład:
str ="<?xml version="1.0" ?><person><name>john</name><age>20</age></person"
dic_xml = convert_to_dic(str)
Wtedy dic_xml
będzie wyglądać{'person' : { 'name' : 'john', 'age' : 20 } }
python
xml
json
dictionary
xml-deserialization
user361526
źródło
źródło
Odpowiedzi:
To świetny moduł, który ktoś stworzył. Używałem go kilka razy. http://code.activestate.com/recipes/410469-xml-as-dictionary/
Oto kod ze strony internetowej na wypadek, gdyby link się zepsuł.
Przykładowe użycie:
// Lub, jeśli chcesz użyć ciągu XML:
źródło
xmltodict
bibliotece). Wadą jest to, że musisz sam go hostować w swoim projekcie.cElementTree
, po prostu zmień pierwszą linię na:from xml.etree import cElementTree as ElementTree
xmltodict (pełne ujawnienie: napisałem) robi dokładnie to:
źródło
Poniższy fragment kodu XML-to-Python-dict analizuje jednostki oraz atrybuty zgodnie z tą „specyfikacją” XML-to-JSON . Jest to najbardziej ogólne rozwiązanie obsługujące wszystkie przypadki XML.
To jest używane:
Dane wyjściowe tego przykładu (zgodnie z powyższą „specyfikacją”) powinny wyglądać następująco:
Niekoniecznie ładne, ale jest jednoznaczne, a prostsze dane wejściowe XML skutkują prostszym JSON. :)
Aktualizacja
Jeśli chcesz zrobić odwrotnie , wyemituj ciąg XML z JSON / dict , możesz użyć:
źródło
d = {t.tag: {k:v[0] if len(v) == 1 else v for k, v in dd.iteritems()}}
nad = { t.tag: dict( (k, v[0] if len(v) == 1 else v) for k, v in dd.iteritems() ) }
cElementTree
lublxml.etree
. Zwróć uwagę, że podczas korzystania z Pythona 3 wszystkie.iteritems()
muszą zostać zmienione na.items()
(to samo zachowanie, ale słowo kluczowe zostało zmienione z Python 2 na 3).Ta lekka wersja, choć nie jest konfigurowalna, jest dość łatwa do dostosowania w razie potrzeby i działa w starych Pythonach. Jest też sztywny - co oznacza, że wyniki są takie same niezależnie od istnienia atrybutów.
Więc:
Prowadzi do:
źródło
Najnowsze wersje bibliotek PicklingTools (1.3.0 i 1.3.1) obsługują narzędzia do konwersji z XML do dykta Pythona.
Pobieranie jest dostępne tutaj: PicklingTools 1.3.1
Jest sporo dokumentacji dla konwerterów tutaj : dokumentacja opisuje szczegółowo wszystkie decyzje i problemów, które wynikną podczas konwersji pomiędzy XML i słowniki Python (istnieje szereg przypadków brzegowych: atrybuty, listy, anonimowe listy, anonimowe dicts, eval itp., których większość konwerterów nie obsługuje). Generalnie jednak konwertery są łatwe w użyciu. Jeśli „example.xml” zawiera:
Następnie, aby przekonwertować go na słownik:
Istnieją narzędzia do konwersji zarówno w C ++, jak i Pythonie: C ++ i Python wykonują konwersję indentyczną, ale C ++ jest około 60 razy szybszy
źródło
Możesz to zrobić dość łatwo za pomocą lxml. Najpierw zainstaluj:
Oto funkcja rekurencyjna, którą napisałem, która wykonuje dla ciebie ciężkie podnoszenie:
Poniższy wariant zachowuje nadrzędny klucz / element:
Jeśli chcesz zwrócić tylko poddrzewo i przekonwertować je na dict, możesz użyć Element.find (), aby pobrać poddrzewo, a następnie przekonwertować je:
Zobacz dokumentację lxml tutaj . Mam nadzieję, że to pomoże!
źródło
Zastrzeżenie: ten zmodyfikowany parser XML został zainspirowany przez Adama Clarka . Oryginalny parser XML działa w większości prostych przypadków. Jednak nie działało to w przypadku niektórych skomplikowanych plików XML. Debugowałem kod wiersz po wierszu i ostatecznie naprawiłem kilka problemów. Jeśli znajdziesz jakieś błędy, daj mi znać. Cieszę się, że mogę to naprawić.
źródło
źródło
Najłatwiejszym w użyciu parserem XML dla Pythona jest ElementTree (od 2,5x wzwyż znajduje się on w standardowej bibliotece xml.etree.ElementTree). Nie sądzę, aby po wyjęciu z pudełka było coś, co robi dokładnie to, czego chcesz. Napisanie czegoś, co zrobi to, co chcesz przy użyciu ElementTree, byłoby dość trywialne, ale po co konwertować na słownik i dlaczego nie używać bezpośrednio ElementTree.
źródło
Kod z http://code.activestate.com/recipes/410469-xml-as-dictionary/ działa dobrze, ale jeśli istnieje wiele elementów, które są takie same w danym miejscu w hierarchii, po prostu je zastępuje.
Dodałem podkładkę między, która wygląda, aby sprawdzić, czy element już istnieje przed self.update (). Jeśli tak, otwiera istniejący wpis i tworzy listy z istniejącego i nowego. Wszelkie kolejne duplikaty są dodawane do listy.
Nie jestem pewien, czy można to zrobić z wdziękiem, ale działa:
źródło
Z @ K3 --- odpowiedź rnc (dla mnie najlepsza) Dodałem małe modyfikacje, aby uzyskać OrderedDict z tekstu XML (czasami kolejność ma znaczenie):
Zgodnie z przykładem @ K3 --- rnc, możesz go użyć:
Mam nadzieję, że to pomoże ;)
źródło
Oto link do rozwiązania ActiveState - i kod na wypadek, gdyby ponownie zniknął.
źródło
W pewnym momencie musiałem przeanalizować i napisać XML, który składał się tylko z elementów bez atrybutów, więc mapowanie 1: 1 z XML do dykt było możliwe. Oto, co wymyśliłem na wypadek, gdyby ktoś inny również nie potrzebował atrybutów:
źródło
@dibrovsd: Rozwiązanie nie będzie działać, jeśli XML ma więcej niż jeden tag o tej samej nazwie
Zgodnie z twoją myślą, zmodyfikowałem nieco kod i napisałem go dla węzła ogólnego zamiast roota:
źródło
Zmodyfikowałem jedną z odpowiedzi według własnego gustu i aby pracować z wieloma wartościami z tym samym tagiem, na przykład rozważ następujący kod xml zapisany w pliku XML.xml
iw Pythonie
wyjście jest
źródło
Mam metodę rekurencyjną, aby uzyskać słownik z elementu lxml
źródło