Объедините файлы XML, похожие на поддержку нескольких файлов в ConfigParser - PullRequest
2 голосов
/ 07 октября 2011

Я пишу модуль конфигурации приложения, который использует 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 ]

1 голос
/ 07 октября 2011

Вы можете преобразовать 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 голосов
/ 07 октября 2011

Должны ли вы использовать 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'}
...