well, well,... look at this! this is new to me! :) so, you can dump the 3 attached files somewhere and run dfoTest.py and check the output (a few comments in the script and some in the _dfo module). I through in an xml file just for quick testing.
I have quite a few variations on this (some has lots of web2py stuff in it that plays nice with dal.py - which is very useful for me (i think I use DAL everywhere now ;) ) anyways, let me know if anything unclear. Mart :)
from xml.etree import ElementTree from pprint import pprint def main(): dictObj = oXml2oDict('./properties/mauiStruct.xml') pprint(dictObj) '''--- get the data as a dictionary ---''' print dictObj['_root_']['propertyfile']['file'] '''--- dictObj['_root_']['name']='bada_build' or you can access it like object attributes ---''' print dictObj._root_.propertyfile.file '''--- dictObj._root_.name = 'bada_build' ---''' root = dict2eTree(dictObj) tree = ElementTree.ElementTree(root) pprint(tree) tree.write('./properties/bada.new.xml') class dictOjectFunction(dict): def __init__(self, initdict=None): if initdict is None: initdict = {} dict.__init__(self, initdict) def __getattr__(self, item): try: return self.__getitem__(item) except KeyError: raise AttributeError def __setattr__(self, item, value): self.__setitem__(item, value) def __str__(self): if self.has_key('_text'): return self.__getitem__('_text') else: return '' @staticmethod def dictOjectFunctionWrapper(dictInst): if isinstance(dictInst, dict): return dictOjectFunction((key, dictOjectFunction.dictOjectFunctionWrapper(value)) for (key, value) in dictInst.iteritems()) elif isinstance(dictInst, list): return [dictOjectFunction.dictOjectFunctionWrapper(value) for value in dictInst] else: return dictInst @staticmethod def _UndictOjectFunctionWrapper(dictInst): if isinstance(dictInst, list): return [dictOjectFunction._UndictOjectFunctionWrapper(value) for value in dictInst] else: return dictInst def UndictOjectFunctionWrapper(self): return dictOjectFunction._UndictOjectFunctionWrapper(self) def _ConvertDictToXmlRecurse(parent, dictObject): assert type(dictObject) is not type([]) if isinstance(dictObject, dict): for (tag, child) in dictObject.iteritems(): if str(tag) == '_text': parent.text = str(child) elif type(child) is type([]): for listchild in child: elem = ElementTree.Element(tag) parent.append(elem) _ConvertDictToXmlRecurse(elem, listchild) else: elem = ElementTree.Element(tag) parent.append(elem) _ConvertDictToXmlRecurse(elem, child) else: parent.text = str(dictObject) def dict2eTree(xmldict): rTag = xmldict.keys()[0] root = ElementTree.Element(rTag) _ConvertDictToXmlRecurse(root, xmldict[rTag]) return root def xml2Dict(elem, dictclass): elemdict = dictclass() if len(elem.items()) > 0: elemdict.update(dict(elem.items())) for child in elem: newitem = xml2Dict(child, dictclass) if elemdict.has_key(child.tag): if type(elemdict[child.tag]) is type([]): elemdict[child.tag].append(newitem) else: elemdict[child.tag] = [elemdict[child.tag], newitem] else: elemdict[child.tag] = newitem if elem.text is None: text = '' else: text = elem.text.strip() if len(elemdict) > 0: if len(text) > 0: elemdict['_text'] = text else: elemdict = text return elemdict def oXml2oDict(root, dictclass=dictOjectFunction): if type(root) == type(''): root = ElementTree.parse(root).getroot() elif not isinstance(root, ElementTree.Element): raise TypeError, 'Expected ElementTree.Element or file path string' return dictclass({root.tag: xml2Dict(root, dictclass)}) #if __name__ == '__main__': # main()
brewmp_29.xml
Description: XML document
'''--- a few imports ---''' import _dfo from pprint import pprint from xml.etree import ElementTree '''--- point to an xml file ---''' myXMlFile='./brewmp_29.xml' '''--- create an object reference to it while passing well formatted xml file ---''' myDfo=_dfo.oXml2oDict(myXMlFile) '''--- print it pretty and see the the dict ---''' pprint(myDfo) '''--- let try it! ---''' print('\n\ntesting the dict!\nmyDfo.build.name: {0}'.format(myDfo.build.name)) print("myDfo['build']['name']: {0}\n\n".format(myDfo['build']['name'])) print('looping through the dict object:') for item in myDfo.build: print('dict item: {0}'.format(item)) print('\n\n') '''--- convert the dict object back to XML & iter through all xml elelments and get the tag names and, why not, the attributes... or whatever eTree processing you want ---''' x=_dfo.dict2eTree(myDfo) y=x.getiterator() for item in y: if len(item)>0: print('{0}\n\t{1}'.format(item,item.tag)) if item.getchildren(): for child in item._children:print('\t\t{0}'.format(child.tag))