- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathxmlDictTools.py
More file actions
Latest commit
executable file
·109 lines (92 loc) · 3.19 KB
/
Copy pathxmlDictTools.py
File metadata and controls
executable file
·109 lines (92 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# Based on http://code.activestate.com/recipes/577722-xml-to-python-dictionary-and-back/
# Create python xml structures compatible with
# http://search.cpan.org/~grantm/XML-Simple-2.18/lib/XML/Simple.pm
fromlxmlimportetree
fromitertoolsimportgroupby
defxml2d(e):
"""Convert an etree into a dict structure
@type e: etree.Element
@param e: the root of the tree
@return: The dictionary representation of the XML tree
"""
# Namespace magic
defns=""
ifNoneine.nsmap:
defns="{{{0}}}".format(e.nsmap[None])
def_xml2d(e):
kids= {}
forkeyindict(e.attrib):
kids["#"+key] =e.attrib[key]
fork, gingroupby(e, lambdax: x.tag):
g= [ _xml2d(x) forxing ]
iflen(g) ==1:
g=g[0]
ifk.startswith(defns):
kids[k.replace(defns,"")]=g
else:
kids[k]=g
ifnotkids:
returne.text.strip()
returnkids
tag=e.tag
iftag.startswith(defns):
tag=tag.replace(defns,"")
return { tag : _xml2d(e), '!namespaces': e.nsmap }
defd2xml(d):
"""convert dict to xml
1. The top level d must contain a single entry i.e. the root element
2. Keys of the dictionary become sublements or attributes
3. Keys that start with # are attributes
4. If a value is a simple string, then the key subelement and the value is text.
5. if a value is dict then, then key is a subelement
6. if a value is list, then key is a set of sublements
a = { 'module' : {'tag' : [ { 'name': 'a', 'value': 'b'},
{ 'name': 'c', 'value': 'd'},
],
'gobject' : { 'name': 'g', 'type':'xx' },
'uri' : 'test',
}
}
>>> d2xml(a)
<module uri="test">
<gobject type="xx" name="g"/>
<tag name="a" value="b"/>
<tag name="c" value="d"/>
</module>
@type d: dict
@param d: A dictionary formatted as an XML document
@return: A etree Root element
"""
def_d2xml(d, p):
fork,vind.items():
ifk.startswith("#"):
p.set(k[1:],v)
elifisinstance(v,dict):
node=etree.SubElement(p, k)
_d2xml(v, node)
elifisinstance(v,list):
foriteminv:
node=etree.SubElement(p, k)
_d2xml(item, node)
else:
node=etree.SubElement(p, k)
node.text=v
# Namespace magic
nsmap=None
if'!namespaces'ind:
nsmap=d['!namespaces']
deld['!namespaces']
k,v=d.items()[0]
ifnsmap:
d['!namespaces'] =nsmap
node=etree.Element(k, nsmap=nsmap)
_d2xml(v, node)
returnnode
if__name__=="__main__":
X="""<T uri="boo"><a n="1"/><a n="2"/><b n="3"><c x="y"/></b><d>Test</d></T>"""
printX
Y=xml2d(etree.XML(X))
printY
Z=etree.tostring (d2xml(Y) )
printZ
assertX==Z