2009-06-19 8 views
58

Istnieje prosty moduł serializacji JSON o nazwie "simplejson", który z łatwością serializuje obiekty Pythona do JSON.Serializuj słownik Pythona do XML

Szukam podobnego modułu, który może serializować do XML.

Odpowiedz

13
+4

> http://code.activestate.com/recipes/415983/ Ten nie serializuje do XML tylko do formatu marszałkowego. A także nie lubię sys.exit w Exception. > http://sourceforge.net/projects/pyxser/ Ten nie jest BSD. Przepraszam, że zapomniałem wspomnieć, szukam modułu Pythona lub BSD, więc mogę rozpowszechniać z moim oprogramowaniem BSD. Ostatnie 2 - dla webservices, szukam regularnego serializatora XML. – zinovii

+1

zdmytriv: możesz rozpowszechniać bibliotekę LGPL z kodem BSD bez zobowiązań. – nosklo

+0

@nosklo: Nie wiedziałem, że możesz to zrobić. Teraz wiem, dzięki. – zinovii

17

Jest huTools.structured.dict2xml który stara się być kompatybilny z simplejson w duchu. Możesz dać mu wskazówki, jak owijać zagnieżdżone podstruktury. Sprawdź dokumentację dla huTools.structured.dict2et, która zwraca ElementTree Obiekty zamiast tego, jeśli ciągi zwracane przez dict2xml.

>>> data = {"kommiauftragsnr":2103839, "anliefertermin":"2009-11-25", "prioritaet": 7, 
... "ort": u"Hücksenwagen", 
... "positionen": [{"menge": 12, "artnr": "14640/XL", "posnr": 1},], 
... "versandeinweisungen": [{"guid": "2103839-XalE", "bezeichner": "avisierung48h", 
...       "anweisung": "48h vor Anlieferung unter 0900-LOGISTIK avisieren"}, 
... ]} 

>>> print ET.tostring(dict2et(data, 'kommiauftrag', 
... listnames={'positionen': 'position', 'versandeinweisungen': 'versandeinweisung'})) 
'''<kommiauftrag> 
<anliefertermin>2009-11-25</anliefertermin> 
<positionen> 
    <position> 
     <posnr>1</posnr> 
     <menge>12</menge> 
     <artnr>14640/XL</artnr> 
    </position> 
</positionen> 
<ort>H&#xC3;&#xBC;cksenwagen</ort> 
<versandeinweisungen> 
    <versandeinweisung> 
     <bezeichner>avisierung48h</bezeichner> 
     <anweisung>48h vor Anlieferung unter 0900-LOGISTIK avisieren</anweisung> 
     <guid>2103839-XalE</guid> 
    </versandeinweisung> 
</versandeinweisungen> 
<prioritaet>7</prioritaet> 
<kommiauftragsnr>2103839</kommiauftragsnr> 
</kommiauftrag>''' 
+0

huTools nie jest kompatybilny z Pythonem 3 (obiekt '' 'dict 'nie ma atrybutu' iteritems'''). – thomaskonrad

+0

Jakie są warunki licencji tego produktu? Czy mogę użyć tej aplikacji komercyjnej? –

11

Wypróbuj ten. Jedynym problemem nie używam atrybutów (bo nie podoba im)
dict2xml on pynuggets.wordpress.com
dict2xml on activestate

from xml.dom.minidom import Document 
import copy 

class dict2xml(object): 
    doc  = Document() 

    def __init__(self, structure): 
     if len(structure) == 1: 
      rootName = str(structure.keys()[0]) 
      self.root = self.doc.createElement(rootName) 

      self.doc.appendChild(self.root) 
      self.build(self.root, structure[rootName]) 

    def build(self, father, structure): 
     if type(structure) == dict: 
      for k in structure: 
       tag = self.doc.createElement(k) 
       father.appendChild(tag) 
       self.build(tag, structure[k]) 

     elif type(structure) == list: 
      grandFather = father.parentNode 
      tagName  = father.tagName 
      grandFather.removeChild(father) 
      for l in structure: 
       tag = self.doc.createElement(tagName) 
       self.build(tag, l) 
       grandFather.appendChild(tag) 

     else: 
      data = str(structure) 
      tag  = self.doc.createTextNode(data) 
      father.appendChild(tag) 

    def display(self): 
     print self.doc.toprettyxml(indent=" ") 

if __name__ == '__main__': 
    example = {'auftrag':{"kommiauftragsnr":2103839, "anliefertermin":"2009-11-25", "prioritaet": 7,"ort": u"Huecksenwagen","positionen": [{"menge": 12, "artnr": "14640/XL", "posnr": 1},],"versandeinweisungen": [{"guid": "2103839-XalE", "bezeichner": "avisierung48h","anweisung": "48h vor Anlieferung unter 0900-LOGISTIK avisieren"},]}} 
    xml = dict2xml(example) 
    xml.display() 
+1

Oto pewien problem z tworzeniem kolejnej instancji dict2xml 'xml.dom.HierarchyRequestErr: dwa elementy dokumentu niedozwolone', , więc dodałem metodę odłączenia: ' def unlink (self): self.doc.unlink() ' –

2

Większość obiektów w Pythonie są reprezentowane dicts pod spodem:

>>> class Fred(object) : 
... def __init__(self, n) : self.n = n 
... 
>>> a = Fred(100) 
>>> print a.__dict__ 
{'n': 100} 

Więc ta jest podobna do pytając, jak konwertować dicts do XML. Istnieją narzędzia do konwersji dict do/z XML pod adresem:

http://www.picklingtools.com

Oto prosty przykład:

>>> import xmltools 

    >>> d = {'a':1, 'b':2.2, 'c':'three' } 
    >>> xx = xmltools.WriteToXMLString(d) 
    >>> print xx 
    <?xml version="1.0" encoding="UTF-8"?> 
    <top> 
     <a>1</a> 
     <b>2.2</b> 
     <c>three</c> 
    </top> 

Istnieje wiele dokumentacji na stronie internetowej pokazując przykłady:

XML Tools Manual

Trudno jest przekonwertować "dokładnie" między dicts i XML: Co to jest lista? Co robisz z atrybutami? Jak radzisz sobie z kluczami numerycznymi? Wiele z tych problemów zostało omówionych jako i omówiono je w dokumentacji narzędzi XML (powyżej).

Czy prędkość ma dla Ciebie znaczenie? A może łatwość użycia ma znaczenie? Istnieje czysty moduł C++ (wszystkie napisane w C++), czysty moduł Pythona (wszystkie napisane w Pythonie) i moduł rozszerzający Python C (napisany w C++, ale zawijany, aby Python mógł go nazwać). Moduł rozszerzający C++ i Python C są szybsze o rząd wielkości, ale oczywiście wymagają kompilacji, aby zacząć. Moduł Pythona powinien działać, ale jest wolniejszy:

8

Napisałem prostą funkcję, która przekształca słowniki na xml (poniżej 30 linii).

wykorzystania:

mydict = { 
    'name': 'The Andersson\'s', 
    'size': 4, 
    'children': { 
     'total-age': 62, 
     'child': [ 
      { 
       'name': 'Tom', 
       'sex': 'male', 
      }, 
      { 
       'name': 'Betty', 
       'sex': 'female', 
      } 
     ] 
    }, 
} 
print(dict2xml(mydict, 'family')) 

Wynik:

<family name="The Andersson's" size="4"> 
     <children total-age="62"> 
       <child name="Tom" sex="male"/> 
       <child name="Betty" sex="female"/> 
     </children> 
</family> 

Pełne źródło (w tym przykładzie) można znaleźć na https://gist.github.com/reimund/5435343/

Uwaga: Ta funkcja serializacji słownika wpisy jako atrybuty zamiast węzłów tekstowych. Modyfikowanie go w celu obsługi tekstu byłoby bardzo łatwe.