2011-10-07 62 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