00001
00002
00003
00004
00005
00006
00007 from xml.etree import ElementTree
00008
00009
00010 def _ns(tag):
00011 return tag[tag.find('}') + 1:]
00012
00013
00014 class XmlDictObject(dict):
00015 """
00016 Adds object like functionality to the standard dictionary.
00017 """
00018 def __init__(self, initdict=None):
00019 if initdict is None:
00020 initdict = {}
00021 dict.__init__(self, initdict)
00022
00023 def __getattr__(self, item):
00024 return self.__getitem__(item)
00025
00026 def __setattr__(self, item, value):
00027 self.__setitem__(item, value)
00028
00029 def __str__(self):
00030 if '_text' in self:
00031 return self.__getitem__('_text')
00032 else:
00033 return ''
00034
00035 @staticmethod
00036 def wrap(x):
00037 """
00038 Static method to wrap a dictionary recursively as an XmlDictObject
00039 """
00040 if isinstance(x, dict):
00041 return XmlDictObject(
00042 (k, XmlDictObject.wrap(v)) for (k, v) in x.iteritems())
00043 elif isinstance(x, list):
00044 return [XmlDictObject.wrap(v) for v in x]
00045 else:
00046 return x
00047
00048 @staticmethod
00049 def _un_wrap(x):
00050 if isinstance(x, dict):
00051 return dict(
00052 (k, XmlDictObject._un_wrap(v)) for (k, v) in x.iteritems())
00053 elif isinstance(x, list):
00054 return [XmlDictObject._un_wrap(v) for v in x]
00055 else:
00056 return x
00057
00058 def un_wrap(self):
00059 """
00060 Recursively converts an XmlDictObject to a standard dictionary and
00061 returns the result.
00062 """
00063 return XmlDictObject._un_wrap(self)
00064
00065
00066 def _convert_dict_to_xml_recurse(parent, dictitem):
00067 assert isinstance(dictitem, dict)
00068
00069 if isinstance(dictitem, dict):
00070 for (tag, child) in dictitem.iteritems():
00071 if str(tag) == '_text':
00072 parent.text = str(child)
00073 elif isinstance(child, list):
00074
00075 for listchild in child:
00076 elem = ElementTree.Element(tag)
00077 parent.append(elem)
00078 _convert_dict_to_xml_recurse(elem, listchild)
00079 else:
00080 elem = ElementTree.Element(tag)
00081 parent.append(elem)
00082 _convert_dict_to_xml_recurse(elem, child)
00083 else:
00084 parent.text = str(dictitem)
00085
00086
00087 def convert_dict_to_xml(xmldict):
00088 """
00089 Converts a dictionary to an XML ElementTree Element
00090 """
00091 roottag = xmldict.keys()[0]
00092 root = ElementTree.Element(roottag)
00093 _convert_dict_to_xml_recurse(root, xmldict[roottag])
00094 return root
00095
00096
00097 def _convert_xml_to_dict_recurse(node, dictclass):
00098 nodedict = dictclass()
00099
00100 if len(node.items()) > 0:
00101
00102 if'attrib' in nodedict:
00103 nodedict['attrib'].update(dict(node.items()))
00104 else:
00105 nodedict['attrib'] = {}
00106 nodedict['attrib'].update(dict(node.items()))
00107
00108
00109
00110 for child in node:
00111
00112 newitem = _convert_xml_to_dict_recurse(child, dictclass)
00113 if _ns(child.tag) in nodedict:
00114
00115 if isinstance(nodedict[_ns(child.tag)], list):
00116
00117 nodedict[_ns(child.tag)].append(newitem)
00118 else:
00119
00120 nodedict[_ns(child.tag)] = [nodedict[_ns(child.tag)], newitem]
00121 else:
00122
00123 nodedict[_ns(child.tag)] = newitem
00124
00125 if node.text is None:
00126 text = None
00127 else:
00128 text = node.text.strip()
00129
00130 if len(nodedict) > 0:
00131
00132
00133 if text is not None and len(text) > 0:
00134 nodedict['_text'] = text
00135 else:
00136
00137 nodedict = text
00138
00139 return nodedict
00140
00141
00142 def convert_xml_to_dict(root, dictclass=XmlDictObject):
00143 """
00144 Converts an ElementTree Element to a dictionary
00145 """
00146 return dictclass(
00147 {_ns(root.tag): _convert_xml_to_dict_recurse(root, dictclass)})