1from xml.etree import cElementTree as ElementTree
2
3class XmlListConfig(list):
4 def __init__(self, aList):
5 for element in aList:
6 if element:
7 # treat like dict
8 if len(element) == 1 or element[0].tag != element[1].tag:
9 self.append(XmlDictConfig(element))
10 # treat like list
11 elif element[0].tag == element[1].tag:
12 self.append(XmlListConfig(element))
13 elif element.text:
14 text = element.text.strip()
15 if text:
16 self.append(text)
17
18
19class XmlDictConfig(dict):
20 '''
21 Example usage:
22
23 >>> tree = ElementTree.parse('your_file.xml')
24 >>> root = tree.getroot()
25 >>> xmldict = XmlDictConfig(root)
26
27 Or, if you want to use an XML string:
28
29 >>> root = ElementTree.XML(xml_string)
30 >>> xmldict = XmlDictConfig(root)
31
32 And then use xmldict for what it is... a dict.
33 '''
34 def __init__(self, parent_element):
35 if parent_element.items():
36 self.update(dict(parent_element.items()))
37 for element in parent_element:
38 if element:
39 # treat like dict - we assume that if the first two tags
40 # in a series are different, then they are all different.
41 if len(element) == 1 or element[0].tag != element[1].tag:
42 aDict = XmlDictConfig(element)
43 # treat like list - we assume that if the first two tags
44 # in a series are the same, then the rest are the same.
45 else:
46 # here, we put the list in dictionary; the key is the
47 # tag name the list elements all share in common, and
48 # the value is the list itself
49 aDict = {element[0].tag: XmlListConfig(element)}
50 # if the tag has attributes, add those to the dict
51 if element.items():
52 aDict.update(dict(element.items()))
53 self.update({element.tag: aDict})
54 # this assumes that if you've got an attribute in a tag,
55 # you won't be having any text. This may or may not be a
56 # good idea -- time will tell. It works for the way we are
57 # currently doing XML configuration files...
58 elif element.items():
59 self.update({element.tag: dict(element.items())})
60 # finally, if there are no child tags and no attributes, extract
61 # the text
62 else:
63 self.update({element.tag: element.text})
64