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()

Attachment: 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))

Reply via email to