''' Version:0.5 author;wujianqiang date:2016/11/13 ''' import xml.etree.ElementTree as ET from collections import Counter from pprint import pprint import json from fnmatch import fnmatch import os class XMLParse(object): def __init__(self): self.data = {} def _open_file(self,filename): return ET.parse(filename).getroot() def _type_select(self,root, sybol='-'): my_type = {} flag =False attrib_data = root.attrib if len(attrib_data) > 0: flag = True data = {sybol + key: value for key, value in attrib_data.items()} my_type.update(data) if len(root): myset = [child.tag for child in root] mydata = Counter(myset) for key, value in mydata.items(): if value > 1: my_type[key] = [] elif value == 1: my_type[key] = {} return my_type else: if flag: if root.text: my_type['#text'] = root.text return my_type else: return root.text def _par(self,root, data, sybol='-'): utdata = self._type_select(root, sybol) if isinstance(data[root.tag], dict): data[root.tag] = utdata elif isinstance(data[root.tag], list): data[root.tag].append(utdata) if len(root) > 0: for item in root: self._par(item, utdata, sybol) def getdata_fromFile(self,filename, outfile=None,sybol='-'): root = self._open_file(filename) self.data[root.tag] = {} if root.attrib: data = {sybol + key: value for key, value in root.attrib.items()} self.data[root.tag].update(data) self._par(root, self.data,sybol) if outfile: file = open(outfile,'w') json.dump(self.data,file) file.close() return True else: return self.data def getdata_fromString(self, stringdata, outfile=None, sybol='-'): root = ET.fromstring(stringdata) self.data[root.tag] = {} if root.attrib: data = {sybol + key: value for key, value in root.attrib.items()} self.data[root.tag].update(data) self._par(root, self.data, sybol) if outfile: file = open(outfile, 'w') json.dump(self.data, file) file.close() return True else: return self.data def _create_sub_Element(self,parnent, data, tag=None, attrib='-', text='#text'): if isinstance(data, dict): for key, value in data.items(): if fnmatch(key, '%s*' % (attrib,)): parnent.attrib.update({key[1:]: value}) elif fnmatch(key, text): parnent.text = value else: if type(value) == str: a = ET.SubElement(parnent, key) a.text = value elif isinstance(value, dict): a = ET.SubElement(parnent, key) self._create_sub_Element(a, value) else: self._create_sub_Element(parnent, value, tag=key) elif isinstance(data, list): for item in data: l = ET.SubElement(parnent, tag) self._create_sub_Element(l, item, tag) else: pass def _create_root_Element(self,data): root_key = data.keys()[0] root = ET.Element(root_key) etre = ET.ElementTree(root) return [root, data[root_key], etre] def _create_Element(self, data, attr='-', text='#text'): root, mydata, tree = self._create_root_Element(data) self._create_sub_Element(root, mydata, attrib=attr, text=text) return tree def create_xml(self,data,outfile=None): if data: root = self._create_Element(data) filename = outfile if outfile else '.temp' root.write(filename) if not outfile: f = open(filename) data = f.readlines()[0] f.close() os.remove(filename) return data else: return None if __name__ == '__main__': xdata = XMLParse() dat = {'data': {'-fictional': 'http://characters.example.com', 'country': [{'-name': 'Liechtenstein', 'gdppc': '141100', 'neighbor': [{'-direction': 'E', '-name': 'Austria'}, {'-direction': 'W', '-name': 'Switzerland'}], 'rank': '1', 'year': '2008'}, {'-name': 'dfd', 'gdppc': '14100', 'neighbor': {'-direction': 'E', '-name': 'wuul'}, 'rank': '3', 'year': {'#text': '208', '-d': 'sd'}}]}} # pprint(xdata.getdata_fromFile('myxml2.xml',sybol='-')) pprint(xdata.create_xml(dat))