#!/usr/bin/env python #-*- coding: ISO-8859-1 -*- # # Author: Valentin Kuznetsov, Cornell University, 2006 # # makeXML converts dictionary to XML file # # The xml -> dict conversion taken from # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/410469 # Code has been modified to detect integer,float types in xml description, # e.g. 0 would lead isOpen=int(0) # system modules import sys, os, string, types import cElementTree as ElementTree # DBS modules from dbsBaseObject import * def sortedDictValues1(adict): items = adict.items() items.sort() return [value for key, value in items] def sortedDictValues3(adict): keys = adict.keys() keys.sort() return map(adict.get, keys) def sortedDictValues(adict): """Sort dictionary keys and return a new dictionary""" keys = adict.keys() keys.sort() return [dict[key] for key in keys] def makeXML(input): """Return a XML string out of provided dictionary. All work is done in L{makeTemplate}.""" s = """\n""" s+= """\n""" s+= "\n" if type(input) is types.ListType: s+="\n" for i in input: s+="" s+= makeTemplate(i) s+="\n\n" s+="" else: s+= makeTemplate(input) s+= "\n" return s def makeTemplate(d,formatString=""): """Create XML structure out of provided dictionary""" s = "" if (d.__class__ is types.DictType) or isinstance(d,DbsBase): for key in d.keys(): if (d[key].__class__ is types.DictType) or isinstance(d[key],DbsBase): s += "\n%s <%s>"%(formatString,key) s += makeTemplate(d[key],formatString+" ") s += "\n%s "%(formatString,key) else: if type(d[key]) is types.IntType: s += """\n%s <%s type="Integer">%d"""%(formatString,key,d[key],key) else: s += "\n%s <%s>%s"%(formatString,key,d[key],key) else: raise "'%s' is not dict type"%d return s class XmlListConfig(list): def __init__(self, aList): for element in aList: if element: # treat like dict if len(element) == 1 or element[0].tag != element[1].tag: self.append(XmlDictConfig(element)) # treat like list elif element[0].tag == element[1].tag: self.append(XmlListConfig(element)) elif element.text: text = element.text.strip() if text: self.append(text) class XmlDictConfig(dict): ''' Example usage: >>> tree = ElementTree.parse('your_file.xml') >>> root = tree.getroot() >>> xmldict = XmlDictConfig(root) Or, if you want to use an XML string: >>> root = ElementTree.XML(xml_string) >>> xmldict = XmlDictConfig(root) And then use xmldict for what it is... a dict. ''' def __init__(self, parent_element): if parent_element.items(): self.update(dict(parent_element.items())) for element in parent_element: # print "element",element.items(),element.text,element.tag if element: # treat like dict - we assume that if the first two tags # in a series are different, then they are all different. if len(element) == 1 or element[0].tag != element[1].tag: aDict = XmlDictConfig(element) # treat like list - we assume that if the first two tags # in a series are the same, then the rest are the same. else: # here, we put the list in dictionary; the key is the # tag name the list elements all share in common, and # the value is the list itself aDict = {element[0].tag: XmlListConfig(element)} # if the tag has attributes, add those to the dict if element.items(): aDict.update(dict(element.items())) self.update({element.tag: aDict}) # this assumes that if you've got an attribute in a tag, # you won't be having any text. This may or may not be a # good idea -- time will tell. It works for the way we are # currently doing XML configuration files... elif element.items(): if element.items()[0][0]=='type': eType = element.items()[0][1] if string.lower(eType)=='integer': self.update({element.tag: int(element.text)}) continue if string.lower(eType)=='float': self.update({element.tag: float(element.text)}) continue self.update({element.tag: dict(element.items())}) # finally, if there are no child tags and no attributes, extract # the text else: self.update({element.tag: element.text}) def compareDicts(dict1,xmldict): xml_dict = sortedDictValues1(xmldict) app_dict = sortedDictValues1(dict(dict1)) if xml_dict != app_dict: print "The original dictionary" print app_dict print "is not identical to the one we got from XML" print xml_dict sys.exit(1) print "Test [OK]" # # main # if __name__ == "__main__": application = {'executable' : 'testexe','version' : 'testversion','family' : 'testfamily'} xml_string = makeXML(application) root = ElementTree.XML(xml_string) xmldict = XmlDictConfig(root) # sort keys of dictionaries compareDicts(dict(application),xmldict)