合并XML文件类似于ConfigParser的多文件支持
我正在写一个应用程序配置模块,它的文件使用XML格式。我们来看一个例子:
<?xml version="1.0" encoding="UTF-8"?>
<Settings>
<PathA>/Some/path/to/directory</PathA>
<PathB>/Another/path</PathB>
</Settings>
现在,我想在一个后面加载的不同文件中覆盖某些元素。下面是覆盖文件的例子:
<?xml version="1.0" encoding="UTF-8"?>
<Settings>
<PathB>/Change/this/path</PathB>
</Settings>
当我用XPath查询这个包含覆盖内容的文档时,我希望得到这样的元素树:
<?xml version="1.0" encoding="UTF-8"?>
<Settings>
<PathA>/Some/path/to/directory</PathA>
<PathB>/Change/this/path</PathB>
</Settings>
这和Python的ConfigParser用它的read()方法的做法类似,不过是用XML来实现的。我该怎么做呢?
2 个回答
0
你真的必须使用XML吗?其实用JSON可以更简单地实现同样的功能:
假设这是第一个配置文件的内容:
text='''
{
"PathB": "/Another/path",
"PathA": "/Some/path/to/directory"
}
'''
这是第二个配置文件的内容:
text2='''{
"PathB": "/Change/this/path"
}'''
然后要把这两个合并,你只需要把它们分别加载到一个dict
(字典)里,然后调用update
方法:
import json
config=json.loads(text)
config2=json.loads(text2)
config.update(config2)
print(config)
这样就得到了Python的dict
:
{u'PathB': u'/Change/this/path', u'PathA': u'/Some/path/to/directory'}
1
你可以把XML转换成一个Python类的实例:
import lxml.etree as ET
import io
class Settings(object):
def __init__(self,text):
root=ET.parse(io.BytesIO(text)).getroot()
self.settings=dict((elt.tag,elt.text) for elt in root.xpath('/Settings/*'))
def update(self,other):
self.settings.update(other.settings)
text='''\
<?xml version="1.0" encoding="UTF-8"?>
<Settings>
<PathA>/Some/path/to/directory</PathA>
<PathB>/Another/path</PathB>
</Settings>'''
text2='''\
<?xml version="1.0" encoding="UTF-8"?>
<Settings>
<PathB>/Change/this/path</PathB>
</Settings>'''
s=Settings(text)
s2=Settings(text2)
s.update(s2)
print(s.settings)
这样就能得到
{'PathB': '/Change/this/path', 'PathA': '/Some/path/to/directory'}