#python #xml #configuration-files
#python #xml #конфигурация-файлы
Вопрос:
Я пишу модуль конфигурации приложения, который использует 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>
Это похоже на то, что делает ConfigParser Python с помощью своего метода 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'}
Комментарии:
1. В конце концов, я пошел с JSON, но я также реализовал это при исследовании по этому вопросу. Создание собственных классов для представления конфигурации — самый чистый способ.
Ответ №2:
Обязательно ли использовать XML? То же самое можно было бы сделать с помощью JSON намного проще: предположим, что это текст из первого файла конфигурации:
text='''
{
"PathB": "/Another/path",
"PathA": "/Some/path/to/directory"
}
'''
и это текст из второго:
text2='''{
"PathB": "/Change/this/path"
}'''
Затем, чтобы объединить to, вы просто загружаете каждый в 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. О JSON не может быть и речи, но я подумал, что XML будет удобен с XPaths и всем таким.