xml-json-yaml 互转

前言: 一个实现了 xml json yaml互转的破脚本,随用随取

  • xml_json_yaml_converter.py
    """
    xml json yaml 互转工具
    
    这个是对 xmltodict 的二次封装
    
    最终这几种数据结构是通过 python 的dict作为中间数据 进行转换的
    
    """
    import _io
    import os
    import json
    import yaml
    import xmltodict
    from copy import deepcopy
    from xml.dom import minidom
    
    
    class Converter:
        
        def __init__(self):
            self.data = None
            self.params = None  # 初始参数
    
        def dict2xml(self):
    
            if not isinstance(self.data, dict):
                raise TypeError(f'dict2xml expected a dict but received a {type(self.data)}')
            if "xml" not in self.data:
                new = dict()
                new["xml"] = deepcopy(self.data)
                self.data = new
    
            return xmltodict.unparse(self.data)
    
        @staticmethod
        def _write_xml_format(string, filename):  # 试了几种方式 输出的xml都在一行, 所以采用如下方式格式化输出xml
            dom = minidom.parseString(string)
            with open(filename, "w") as f:
                dom.writexml(f, "", "\t", "\n", encoding="utf-8")
                f.flush()
    
        def xml2dict(self):
            if isinstance(self.data, str):
                return xmltodict.parse(self.data)
    
            elif isinstance(self.data, _io.TextIOWrapper):
                return xmltodict.parse(self.data.read())
    
            raise TypeError(f'xml2dict expected a string or _io.TextIOWrapper, but received a {self.data}')
    
        def dict2yaml(self):
            if not isinstance(self.data, dict):
                raise TypeError(f'dict2yaml expected a dict but received a {type(self.data)}')
    
            return yaml.safe_dump(self.data)
    
        def yaml2dict(self):
            if isinstance(self.data, str):
                return yaml.safe_load(self.data)
    
            elif isinstance(self.data, _io.TextIOWrapper):
                return yaml.safe_load(self.data)
    
            raise TypeError(f'from_yaml expected a string or _io.TextIOWrapper, but received a {self.data}')
    
        def dict2json(self):
    
            if not isinstance(self.data, dict):
                raise TypeError(f'to_json expected a dict but received a {type(self.data)}')
    
            return json.dumps(self.data, indent=4)
    
        def json2dict(self):
            if isinstance(self.data, str):
                return json.loads(self.data)
    
            elif isinstance(self.data, _io.TextIOWrapper):
                return json.load(self.data)
    
            raise TypeError(f'from_json expected a string or _io.TextIOWrapper, but received a {self.data}')
    
        def _fd(self, data):
            """返回文件句柄 带后缀的文件名称 将先进入这里 open 返回句柄"""
            return open(data, encoding="utf-8")
    
        # -------------------------------------------- 以上全是 dict 和 结构互转 下面是接口 ----------------------------------
    
        def pre_converter(self, data):
            self.params = data
    
            if isinstance(data, str):
                endswith = os.path.splitext(data)
                if len(endswith) == 2:  # 传参是 一个带后缀的文件地址
                    self.data = self._fd(data)
                    self.params = endswith[0]  # 拿到前缀作为输出的文件前缀
            else:
    
                self.data = data
    
        def hook_converter(self, value, endswith):  # 转换后的操作 写入文件之类
    
            if self.params is not None:
                filename = self.params + "." + endswith
                if endswith == "xml":
                    self._write_xml_format(value, filename)
                else:
                    with open(filename, "w") as f:
                        f.write(value)
                        f.flush()
    
        def xml2json(self, data):
            self.pre_converter(data)
            self.data = self.xml2dict()
            value = self.dict2json()
            self.hook_converter(value, "json")
    
        def xml2yaml(self, data):
            self.pre_converter(data)
            self.data = self.xml2dict()
            value = self.dict2yaml()
            self.hook_converter(value, "yaml")
    
        def json2xml(self, data):
            self.pre_converter(data)
            self.data = self.json2dict()
            value = self.dict2xml()
            self.hook_converter(value, "xml")
    
        def json2yaml(self, data):
            self.pre_converter(data)
            self.data = self.json2dict()
            value = self.dict2yaml()
            self.hook_converter(value, "yaml")
    
        def yaml2xml(self, data):
            self.pre_converter(data)
            self.data = self.yaml2dict()
            value = self.dict2xml()
            self.hook_converter(value, "xml")
    
        def yaml2json(self, data):
            self.pre_converter(data)
            self.data = self.yaml2dict()
            value = self.dict2json()
            self.hook_converter(value, "json")
    
    
    if __name__ == '__main__':
        import fire
    
        fire.Fire(Converter)
    
  • 命令
    是一个简单的命令行,做太多功能,简陋一点
    • python3 xml_json_yaml_converter.py xml2json xx.xml 在当前目录下生成同名的json文件
    • python3 xml_json_yaml_converter.py json2xml xx.json 在当前目录下生成同名的xml文件
    • 其余命令参考上面

你可能感兴趣的:(Python技术,json,xml,python,yaml)