如何在Python中将XML编辑为字典?
我正在尝试用Python从一个模板XML文件生成定制的XML文件。
简单来说,我想先读取这个模板XML文件,然后删除一些元素,修改一些文本属性,最后把新的XML写入一个文件。我希望它能像这样工作:
conf_base = ConvertXmlToDict('config-template.xml')
conf_base_dict = conf_base.UnWrap()
del conf_base_dict['root-name']['level1-name']['leaf1']
del conf_base_dict['root-name']['level1-name']['leaf2']
conf_new = ConvertDictToXml(conf_base_dict)
现在我想把内容写入文件,但我不知道怎么使用 ElementTree.ElementTree.write() 这个方法。
conf_new.write('config-new.xml')
有没有什么办法可以做到这一点,或者有人能建议我用其他方法吗?
8 个回答
11
我不太确定先把信息集转换成嵌套字典是否更简单。使用ElementTree,你可以这样做:
import xml.etree.ElementTree as ET
doc = ET.parse("template.xml")
lvl1 = doc.findall("level1-name")[0]
lvl1.remove(lvl1.find("leaf1")
lvl1.remove(lvl1.find("leaf2")
# or use del lvl1[idx]
doc.write("config-new.xml")
ElementTree的设计就是为了让你不需要先把XML树转换成列表和属性,因为它内部正是这样处理的。
它还支持一小部分的XPath。
19
这个方法可以让你得到一个没有属性的字典。我不知道这对谁有用。我自己在寻找把xml转换成字典的解决方案时,想到了这个。
import xml.etree.ElementTree as etree
tree = etree.parse('test.xml')
root = tree.getroot()
def xml_to_dict(el):
d={}
if el.text:
d[el.tag] = el.text
else:
d[el.tag] = {}
children = el.getchildren()
if children:
d[el.tag] = map(xml_to_dict, children)
return d
这个链接: http://www.w3schools.com/XML/note.xml
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
会等于这个:
{'note': [{'to': 'Tove'},
{'from': 'Jani'},
{'heading': 'Reminder'},
{'body': "Don't forget me this weekend!"}]}
8
在Python中,处理XML文件很方便,我喜欢用Beautiful Soup这个库。它的工作方式大致是这样的:
示例XML文件:
<root>
<level1>leaf1</level1>
<level2>leaf2</level2>
</root>
Python代码:
from BeautifulSoup import BeautifulStoneSoup, Tag, NavigableString
soup = BeautifulStoneSoup('config-template.xml') # get the parser for the xml file
soup.contents[0].name
# u'root'
你可以把节点名称当作方法来使用:
soup.root.contents[0].name
# u'level1'
也可以使用正则表达式:
import re
tags_starting_with_level = soup.findAll(re.compile('^level'))
for tag in tags_starting_with_level: print tag.name
# level1
# level2
添加和插入新节点非常简单:
# build and insert a new level with a new leaf
level3 = Tag(soup, 'level3')
level3.insert(0, NavigableString('leaf3')
soup.root.insert(2, level3)
print soup.prettify()
# <root>
# <level1>
# leaf1
# </level1>
# <level2>
# leaf2
# </level2>
# <level3>
# leaf3
# </level3>
# </root>