XML与JSON/字典互相转换
其实一直都不太喜欢xml,相比json,非常之难用。之前看到过超过300页的专门讲xml的书,应该还是我没有理解xml的独到之处吧。今天写一些东西必须要用到xml,所以随手写了个xml和python字典互相转化的代码。 言归正传:当然是不可能简单的完美转换的啦,至少xml的节点还有attribute,当然硬要存下来,也可以用一些关键字做key或者其他手段。 不过对我要做的事儿,是不需要关心attribute属性的,所以代码就前提就是完全忽略了attribute。 经过一番考虑 并 结合代码的便利性,确定了下面的转换格式
<root>
<person age="18">
<name>hzj</name>
<sex>man</sex>
</person>
<person age="19" des="hello">
<name>kiki</name>
<sex>female</sex>
</person>
<person2 age="19" des="hello">
<name>kiki</name>
<sex>female</sex>
</person2>
</root>
# ==>
{
'person2': {
'name': 'kiki',
'sex': 'female'
},
'person': [
{
'name': 'hzj',
'sex': 'man'
},
{
'name': 'kiki',
'sex': 'female'
}
]
}
可能细心的会注意到:xml 的 root tag在转换后没有了! 是的,原因是:
- xml的标准是根节点必须只有一个,所以没必要再套一层
- 便于编码,可以只使用一个递归函数,就完成转换(主要原因,一写就发现了)。
下面是规则和代码:
'''
实现xml和python字典之间的互相转换
规则为:
1. node的attribute全部忽略
2. xml转换到dict的时候,root的tag会被忽略掉,所以结果的最外层的key为xml的第一级子节点的tag
3. dict转xml第2条的逆向,所以需要手动指定一个root的tag
4. xml中有相同tag名的兄弟节点,在转换成dict的时候会变成一个list(因为python的dict是hash字典,不允许重复key)
'''
from xml.etree.ElementTree import Element
def xml2dict(element):
assert isinstance(element,Element)
ret = {}
for child in list(element):
print child.tag,child.text
if len(child) != 0:
value = xml2dict(child)
else:
value = child.text
if child.tag in ret:
if type(ret[child.tag]) != list:
ret[child.tag] = [ret[child.tag]]
ret[child.tag].append(value)
else:
ret[child.tag] = value
return ret
def dict2xml(root,content):
if type(content) == str or type(content) == unicode:
e = Element(root)
e.text = content
return e
e = Element(root)
for key in content:
if type(content[key]) == list:
for one in content[key]:
e.append(dict2xml(key,one))
else:
e.append(dict2xml(key,content[key]))
return e
完整的包含测试的在这里: https://github.com/dingyaguang117/PythonGist/blob/master/xml_dict.py
Back