XML 存储类,可方便转换为 Dict
| 4 | |
| 5 | |
| 6 | class XMLStore(object): |
| 7 | """ |
| 8 | XML 存储类,可方便转换为 Dict |
| 9 | """ |
| 10 | def __init__(self, xmlstring): |
| 11 | self._raw = xmlstring |
| 12 | self._doc = minidom.parseString(xmlstring) |
| 13 | |
| 14 | @property |
| 15 | def xml2dict(self): |
| 16 | """ |
| 17 | 将 XML 转换为 dict |
| 18 | """ |
| 19 | self._remove_whitespace_nodes(self._doc.childNodes[0]) |
| 20 | return self._element2dict(self._doc.childNodes[0]) |
| 21 | |
| 22 | def _element2dict(self, parent): |
| 23 | """ |
| 24 | 将单个节点转换为 dict |
| 25 | """ |
| 26 | d = {} |
| 27 | for node in parent.childNodes: |
| 28 | if not isinstance(node, minidom.Element): |
| 29 | continue |
| 30 | if not node.hasChildNodes(): |
| 31 | continue |
| 32 | |
| 33 | if node.childNodes[0].nodeType == minidom.Node.ELEMENT_NODE: |
| 34 | try: |
| 35 | d[node.tagName] |
| 36 | except KeyError: |
| 37 | d[node.tagName] = [] |
| 38 | d[node.tagName].append(self._element2dict(node)) |
| 39 | elif len(node.childNodes) == 1 and node.childNodes[0].nodeType in [minidom.Node.CDATA_SECTION_NODE, minidom.Node.TEXT_NODE]: |
| 40 | d[node.tagName] = node.childNodes[0].data |
| 41 | return d |
| 42 | |
| 43 | def _remove_whitespace_nodes(self, node, unlink=True): |
| 44 | """ |
| 45 | 删除空白无用节点 |
| 46 | """ |
| 47 | remove_list = [] |
| 48 | for child in node.childNodes: |
| 49 | if child.nodeType == Node.TEXT_NODE and not child.data.strip(): |
| 50 | remove_list.append(child) |
| 51 | elif child.hasChildNodes(): |
| 52 | self._remove_whitespace_nodes(child, unlink) |
| 53 | for node in remove_list: |
| 54 | node.parentNode.removeChild(node) |
| 55 | if unlink: |
| 56 | node.unlink() |