#!/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 %s>"%(formatString,key)
else:
if type(d[key]) is types.IntType:
s += """\n%s <%s type="Integer">%d%s>"""%(formatString,key,d[key],key)
else:
s += "\n%s <%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)