python3将字典转换成xml

将字典转成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)

运行截图:


企业微信截图_16507862679149.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容