前言: 一个实现了 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文件
- … 其余命令参考上面



