1 '''
2 Created on 03-Dec-2012
3
4 @author: Anil Kumar (anilkumar.s@paxterrasolutions.com)
5 '''
6
7 """
8 xmldict
9 ~~~~~~~~~~~~~~~~~~~~~~~~~
10
11 Convert xml to python dictionaries.
12 """
13 import datetime
14
16 """
17 Converts `root_or_str` which can be parsed xml or a xml string to dict.
18
19 """
20 root = root_or_str
21 if isinstance(root, str):
22 import xml.etree.cElementTree as ElementTree
23 root = ElementTree.XML(root_or_str)
24 return {root.tag: _from_xml(root, strict)}
25
27 """
28 Converts `dict_xml` which is a python dict to corresponding xml.
29 """
30 return _to_xml(dict_xml)
31
33 """
34 Converts `el` to its xml representation.
35 """
36 val = None
37 if isinstance(el, dict):
38 val = _dict_to_xml(el)
39 elif isinstance(el, bool):
40 val = str(el).lower()
41 else:
42 val = el
43 if val is None: val = 'null'
44 return val
45
47 """
48 Extracts attributes from dictionary `els`. Attributes are keys which start
49 with '@'
50 """
51 if not isinstance(els, dict):
52 return ''
53 return ''.join(' %s="%s"' % (key[1:], value) for key, value in els.iteritems()
54 if key.startswith('@'))
55
57 """
58 Converts `els` which is a python dict to corresponding xml.
59 """
60 def process_content(tag, content):
61 attrs = _extract_attrs(content)
62 text = isinstance(content, dict) and content.get('#text', '') or ''
63 return '<%s%s>%s%s</%s>' % (tag, attrs, _to_xml(content), text, tag)
64
65 tags = []
66 for tag, content in els.iteritems():
67
68 if tag.startswith('@') or tag == '#text':
69 continue
70 elif isinstance(content, list):
71 for el in content:
72 tags.append(process_content(tag, el))
73 elif isinstance(content, dict):
74 tags.append(process_content(tag, content))
75 else:
76 tags.append('<%s>%s</%s>' % (tag, _to_xml(content), tag))
77 return ''.join(tags)
78
80 """
81 Returns true if `el` is supposed to be a dict.
82 This function makes sense only in the context of making dicts out of xml.
83 """
84 if len(el) == 1 or el[0].tag != el[1].tag:
85 return True
86 return False
87
89 """
90 Returns true if `el` is supposed to be a list.
91 This function makes sense only in the context of making lists out of xml.
92 """
93 if len(el) > 1 and el[0].tag == el[1].tag:
94 return True
95 return False
96
98 try:
99 val = datetime.datetime.strptime(date_str, "%Y-%m-%dT%H:%M:%SZ")
100 except ValueError:
101 val = date_str
102 return val
103
105 if bool_str.lower() != 'false' and bool(bool_str):
106 return True
107 return False
108
110 """
111 Extracts value of xml element element `el`.
112 """
113 val = None
114
115 if el:
116 if _is_xml_el_dict(el):
117 val = _dict_from_xml(el, strict)
118 elif _is_xml_el_list(el):
119 val = _list_from_xml(el, strict)
120
121 else:
122 attribs = el.items()
123
124 if attribs and strict:
125 val = dict(('@%s' % k, v) for k, v in dict(attribs).iteritems())
126 if el.text:
127 converted = _val_and_maybe_convert(el)
128 val['#text'] = el.text
129 if converted != el.text:
130 val['#value'] = converted
131 elif el.text:
132
133 val = _val_and_maybe_convert(el)
134 elif attribs:
135 val = dict(attribs)
136 return val
137
139 """
140 Converts `el.text` if `el` has attribute `type` with valid value.
141 """
142 text = el.text.strip()
143 data_type = el.get('type')
144 convertor = _val_and_maybe_convert.convertors.get(data_type)
145 if convertor:
146 return convertor(text)
147 else:
148 return text
149 _val_and_maybe_convert.convertors = {
150 'boolean': _str_to_boolean,
151 'datetime': _str_to_datetime,
152 'integer': int
153 }
154
156 """
157 Converts xml elements list `el_list` to a python list.
158 """
159
160 temp = {}
161 for el in els:
162 tag = el.attrib["name"]
163 temp[tag] = (_from_xml(el, strict))
164 return temp
165
167 """
168 Converts xml doc with root `root` to a python dict.
169 """
170
171 res = {}
172 for el in els:
173 res[el.tag] = _from_xml(el, strict)
174 return res
175