我正在尝试从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')
有没有办法做到这一点,或者有人建议以不同的方式做这件事?
答案 0 :(得分:19)
如果这对任何人都有用,这会让你得到一个减去属性的字典... dunno。当我想出这个时,我正在寻找一个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!"}]}
答案 1 :(得分:11)
我不确定是否首先将信息集转换为嵌套dicts更容易。使用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的小子集。
答案 2 :(得分: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>
答案 3 :(得分:4)
我修改丹尼尔的答案,给出一个简洁的字典:
def xml_to_dictionary(element):
l = len(namespace)
dictionary={}
tag = element.tag[l:]
if element.text:
if (element.text == ' '):
dictionary[tag] = {}
else:
dictionary[tag] = element.text
children = element.getchildren()
if children:
subdictionary = {}
for child in children:
for k,v in xml_to_dictionary(child).items():
if k in subdictionary:
if ( isinstance(subdictionary[k], list)):
subdictionary[k].append(v)
else:
subdictionary[k] = [subdictionary[k], v]
else:
subdictionary[k] = v
if (dictionary[tag] == {}):
dictionary[tag] = subdictionary
else:
dictionary[tag] = [dictionary[tag], subdictionary]
if element.attrib:
attribs = {}
for k,v in element.attrib.items():
attribs[k] = v
if (dictionary[tag] == {}):
dictionary[tag] = attribs
else:
dictionary[tag] = [dictionary[tag], attribs]
return dictionary
namespace是xmlns字符串,包括大括号,ElementTree会预先添加到所有标签,所以我在这里清除它,因为整个文档有一个名称空间
请注意,我也调整了原始xml,因此'empty'标签最多只能生成ElementTree表示中的'text属性
spacepattern = re.compile(r'\s+')
mydictionary = xml_to_dictionary(ElementTree.XML(spacepattern.sub(' ', content)))
会给出例如
{'note': {'to': 'Tove',
'from': 'Jani',
'heading': 'Reminder',
'body': "Don't forget me this weekend!"}}
它是为特定的xml设计的,它基本上等同于json,应该处理元素属性,如
<elementName attributeName='attributeContent'>elementContent</elementName>
太
有可能合并属性字典/子标签字典与重复子标签的合并方式类似,尽管嵌套列表似乎是合适的: - )
答案 4 :(得分:1)
添加此行
d.update(('@' + k, v) for k, v in el.attrib.iteritems())
<{3>}中的您也可以拥有节点属性。
在这篇文章user247686's code
中找到它示例:强>
import xml.etree.ElementTree as etree
from urllib import urlopen
xml_file = "http://your_xml_url"
tree = etree.parse(urlopen(xml_file))
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)
d.update(('@' + k, v) for k, v in el.attrib.iteritems())
return d
呼叫
xml_to_dict(root)
答案 5 :(得分:0)
你试过这个吗?
print xml.etree.ElementTree.tostring( conf_new )
答案 6 :(得分:0)
对我来说最直接的方式:
root = ET.parse(xh)
data = root.getroot()
xdic = {}
if data > None:
for part in data.getchildren():
xdic[part.tag] = part.text
答案 7 :(得分:0)
XML具有丰富的信息集,在Python字典中表示它需要一些特殊的技巧。元素是有序的,属性与元素主体等区分开来。
一个处理XML和Python字典之间往返的项目,有一些用于以不同方式处理权衡的配置选项是XML Support in Pickling Tools。需要1.3及更高版本。它不是纯Python(事实上它的目的是使C ++ / Python交互更容易),但它可能适用于各种用例。