3 def xml_file_to_object(filename):
4 """Turns the contents of an XML file into a Python object"""
5 doc = xml.dom.minidom.parse(filename)
6 obj = xml_node_to_object(doc.documentElement)
10 def xml_string_to_object(string):
11 """Turns an XML string into a Python object"""
12 doc = xml.dom.minidom.parseString(string)
13 obj = xml_node_to_object(doc.documentElement)
17 def xml_node_to_object(xml_node):
18 """Turns an XML node into a Python object"""
21 if xml_node.nodeType != xml_node.ELEMENT_NODE:
25 node_name = xml_node.nodeName
27 for node_child in xml_node.childNodes:
28 if node_child.nodeType == xml_node.ELEMENT_NODE:
29 sub_obj = xml_node_to_object(node_child)
30 __append_child_node(obj, node_name, node_child.nodeName, sub_obj)
33 for attr in xml_node.attributes.values():
34 __append_child_node(obj, node_name, attr.name,
35 dict([(attr.name, attr.value)]))
38 if not done and len(xml_node.childNodes) > 0:
39 # If the node has no element children, clean up the text
40 # content and use that as the data
41 text_node = xml_node.childNodes[0] # extract the text node
42 data = unicode(text_node.nodeValue).replace('^\s*','')
43 data = data.replace('\s*$','')
46 # the current element contains attributes and text
47 obj[node_name]['#text'] = data
49 # the current element contains text only
55 def __append_child_node(obj, node_name, child_name, sub_obj):
56 """ If a node has element children, create a new sub-object
57 for this node, attach an array for each type of child
58 and recursively collect the children data into the array(s) """
60 if not obj.has_key(node_name):
63 if not obj[node_name].has_key(child_name):
64 # we've encountered 1 sub-node with node_child's name
65 if child_name in sub_obj:
66 obj[node_name][child_name] = sub_obj[child_name]
68 obj[node_name][child_name] = None
71 if isinstance(obj[node_name][child_name], list):
72 # we already have multiple sub-nodes with node_child's name
73 obj[node_name][child_name].append(sub_obj[child_name])
76 # we already have 1 sub-node with node_child's name, make
77 # it a list and append the current node
78 val = obj[node_name][child_name]
79 obj[node_name][child_name] = [ val, sub_obj[child_name] ]