2011-10-07 60 views
2

我正在编写一个在其文件中使用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完成。我怎样才能实现这个?

回答

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'} 
+0

最后我确实使用了JSON,但是在研究这个主题时我也实现了这一点。创建自己的类来表示配置是最干净的方式。 – tuomur

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'} 
+0

JSON是不是出了问题,但我认为XML将方便XPath和所有这一切。 – tuomur