将字典转成xml,有一个常用的库dicttoxml,但转换出来的xml文件多了很多冗余属性(相对于我们公司协议而言),因此基于内置的xml模块实现一个类似字典转xml的方法,一句老话"适合自己的才是最好的"。代码如下:
# coding:utf-8
from xml.dom import minidom
class DictToXML:
"""
将字典转成xml格式
data = {"a": "123", "b": "124", "c": [{"d": "d124"}, {"d2": "d123"}], "e": {"e1": "e1", "e2": "中国"}}
# 实例化对象 将根节点名称定义为MSG
xml = DictToXML(data,root="MSG")
# 根据tag名称设置属性
xml.set_attribute_by_tag("c", {"name": "ddd", "cls": "dd2"})
# 打印转换后的xml字符串
print(xml.toxml)
# 打印对象,格式化xml文本
print(xml) ->
<?xml version="1.0" encoding="UTF-8"?><MSG><a>123</a><b>124</b><c name="ddd" cls="dd2"><d>d124</d><d2>d123</d2></c><e><e1>e1</e1><e2>中国</e2></e></MSG>
<?xml version="1.0" encoding="UTF-8"?>
<MSG>
<a>123</a>
<b>124</b>
<c name="ddd" cls="dd2">
<d>d124</d>
<d2>d123</d2>
</c>
<e>
<e1>e1</e1>
<e2>中国</e2>
</e>
</MSG>
"""
def __init__(self, data: dict, root="root", encoding="UTF-8"):
self.XML = minidom.Document()
self.encoding = encoding
self.root = self.XML.createElement(root)
self.XML.appendChild(self.root)
self.__to_xml(data, self.root)
def set_attribute_by_tag(self, tag_name, attrs_dict: dict):
"""
根据tag名称设置属性
:param tag_name:
:param attrs_dict:
"""
elements = self.XML.getElementsByTagName(tag_name)
for element in elements:
for k, v in attrs_dict.items():
element.setAttribute(k, v)
def add_text_node(self, parent, name, data=""):
"""
添加文本节点
:param parent:父节点
:param name: 节点名称
:param data: 节点内容,调用str方法转换为字符串
:return:
"""
node = self.XML.createElement(name)
node.appendChild(self.XML.createTextNode(str(data)))
parent.appendChild(node)
return node
def __to_xml(self, data_dict: dict, parent_node):
"""
将字典转化为xml,
:param data_dict:
:param parent_node: 父节点
"""
for tag_name, v in data_dict.items():
if isinstance(v, str):
child_node = self.add_text_node(parent_node, tag_name, v)
elif isinstance(v, list):
child_node = self.XML.createElement(tag_name)
for child in v:
if isinstance(child, dict):
self.__to_xml(child, parent_node=child_node)
elif isinstance(v, dict):
child_node = self.XML.createElement(tag_name)
self.__to_xml(v, child_node)
else:
raise ValueError(f"不支持的转化类型:{tag_name}->{v}")
parent_node.appendChild(child_node)
def __str__(self) -> str:
return self.XML.toprettyxml(encoding=self.encoding).decode()
@property
def toxml(self) -> str:
return self.XML.toxml(encoding=self.encoding).decode()
if __name__ == "__main__":
data = {"a": "123", "b": "124", "c": [{"d": "d124"}, {"d2": "d123"}], "e": {"e1": "e1", "e2": "中国"}}
xml = DictToXML(data, root="MSG")
xml.set_attribute_by_tag("c", {"name": "ddd", "cls": "dd2"})
print(xml.toxml)
print(xml)
运行截图: