目录
一、问题起源
最近遇到个接口,需要将XML转换为form-data格式,并排序,排序后再加密。
大家都知道python的字典和json类似,那么可不可以先将xml转换成json再去做其他的事情呢?答案是可以的。
二、实现
1.下面的Python代码将任意XML格式文件转化为JSON格式(字典)。除Python自带的模块外,不需要依赖其他任何第三方库。
2.XML文件的读取使用Python自带的XML模块。
3.部分关键代码如下:
扫描二维码关注公众号,回复:
15284849 查看本文章
import xml.etree.ElementTree as ET
import json
def xml2json(node):
if not isinstance(node, ET.Element):
raise Exception("node format error.")
if len(node) == 0:
return node.tag, node.text
data = {}
temp = None
for child in node:
key, val = xml2json(child)
if key in data:
if type(data[key]) == list:
data[key].append(val)
else:
temp = data[key]
data[key] = [temp, val]
else:
data[key] = val
return node.tag, data
4.测试代码如下:
def main():
path = "./temp.xml"
tree = ET.parse(path)
node = tree.getroot()
tag, data = xml2json(node)
f = open("./temp.json", "w", encoding="utf-8")
f.write(json.dumps(data, ensure_ascii=False, indent=4))
f.close()
5.结果如下:
(1)原XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<观测区域>
<坐标列表>
<坐标>
<经度>76.940</经度>
<纬度>-77.21</纬度>
</坐标>
<坐标>
<经度>81.7</经度>
<纬度>-76.4</纬度>
</坐标>
<坐标>
<经度>64</经度>
<纬度>-66</纬度>
</坐标>
<坐标>
<经度>63.5</经度>
<纬度>-65.3</纬度>
</坐标>
<坐标>
<经度>60.8</经度>
<纬度>-66.4</纬度>
</坐标>
<坐标>
<经度>60.2</经度>
<纬度>-66.3</纬度>
</坐标>
<坐标>
<经度>76.4</经度>
<纬度>-77.2</纬度>
</坐标>
</坐标列表>
<名称>普通观测</名称>
</观测区域>
(2)转换后的JSON文件:
{
"坐标列表": {
"坐标": [
{
"经度": "76.940",
"纬度": "-77.21"
},
{
"经度": "81.7",
"纬度": "-76.4"
},
{
"经度": "64",
"纬度": "-66"
},
{
"经度": "63.5",
"纬度": "-65.3"
},
{
"经度": "60.8",
"纬度": "-66.4"
},
{
"经度": "60.2",
"纬度": "-66.3"
},
{
"经度": "76.4",
"纬度": "-77.2"
}
]
},
"名称": "普通观测"
}
三 最终完成效果
最后提供一下完整的代码,方便大家使用
#字符处理单元
import json
import xmltodict
def xml_to_dict(child_root,xml_dic=None):
# xml解析器
xml_par = xmltodict.parse(xml_dic)
xml_par =xml_par[child_root]
# 通过dumps()方法转换成json,格式化json,index=1
json_dic = json.dumps(xml_par, indent=1)
# 返回直接把null值替换成‘’
return json_dic.replace("null", "''")
#json转from表单排序
def json2formdata(in_json):
dict_a = json.loads(in_json)
dict_b = sorted(dict_a.items(), key=lambda x: x[0], reverse=False) #reverse从小到大排,true, 从大到小
str_res = ''
icount = len(dict_b)
i = 1
for dict_str in dict_b:
if i == icount:
str_res = str_res + dict_str[0] + '=' + str(dict_str[1])
else:
str_res = str_res +dict_str[0] + '=' + str(dict_str[1]) + '&'
i += 1
return str_res
def xml2formdata(in_xml,rootname):
sjson = xml_to_dict(rootname,in_xml)
print(sjson)
return json2formdata(sjson)
class GetHashCode:
def convert_n_bytes(self, n, b):
bits = b * 8
return (n + 2 ** (bits - 1)) % 2 ** bits - 2 ** (bits - 1)
def convert_4_bytes(self, n):
return self.convert_n_bytes(n, 4)
@classmethod
def getHashCode(cls, s):
h = 0
n = len(s)
for i, c in enumerate(s):
h = h + ord(c) * 31 ** (n - 1 - i)
return cls().convert_4_bytes(h)
if __name__ == '__main__':
# hashCode = GetHashCode.getHashCode("17d27eb55a1127.0.0.1")
# print(hashCode)
# print(json2formdata('{"a":"1","c":"2","b":"3","d":"1"}'))
request_info = "<root><vaa1>sasasasa</vaa1><aaa1>asasasasa</aaa1></root>"
print(xml2formdata(request_info,'root'))