Редактирование значений в файле xml с помощью Python

Привет. Я хочу иметь файл config.xml для настроек в веб-приложении Python.

Я создал файл car.xml вручную. Это выглядит так:

<car>
    <lights>
        <blinkers>off</blinkers>
    </lights>
</car>

Теперь я хочу посмотреть, включены ли поворотники, используя xml.etree.ElementTree.

import xml.etree.ElementTree as ET
tree = ET.parse('car.xml')
blinkers = tree.findtext('lights/blinkers')
print blinkers
> off

Теперь я хочу включать и выключать поворотники, как мне это сделать?


person Frode    schedule 03.10.2010    source источник
comment
вам действительно не нужен xml-файл. Вам нужно простое имя модуля Python settings с константами уровня модуля в ALLCAPS, в котором есть любая информация, которую вы хотели сохранить в xml. У вас могут быть кортежи, списки, словари, целые числа, числа с плавающей запятой и т. д. Когда какой-либо части вашего приложения требуется настройка FOO, она может просто выполнить import settings; settings.FOO.   -  person aaronasterling    schedule 03.10.2010
comment
Я вижу, как это было бы быстрее и проще для настроек, спасибо. Но скажем, у меня есть CMS, которая хранит статьи в формате xml, если бы шоры были «заголовком», как бы я изменил этот заголовок.   -  person Frode    schedule 03.10.2010


Ответы (5)


XML — довольно плохой способ хранения настроек конфигурации. Во-первых, XML не совсем удобен для человека в контексте настроек. В частности, во вселенной Python вам лучше использовать модуль настроек (как прокомментировал @AaronMcSmooth). К сожалению, многие проекты в мире Java (неправильно?) использовали XML для настроек, что сделало его тенденцией. Я бы сказал, что эта тенденция действительно отстой. Используйте собственные настройки (модуль на Python) или что-то более удобное для человека, например YAML.

person Manoj Govindan    schedule 03.10.2010

Вы можете удалить узлы, вызвав метод remove родительского узла, и вставить узлы, вызвав ET.SubElement:

import xml.etree.ElementTree as ET

def flip_lights(tree):
    lights = tree.find('lights')
    state=get_blinker(tree)
    blinkers = tree.find('lights/blinkers')
    lights.remove(blinkers)
    new_blinkers = ET.SubElement(lights, "blinkers")
    new_blinkers.text='on' if state=='off' else 'off'

def get_blinker(tree):
    blinkers = tree.find('lights/blinkers')
    return blinkers.text

tree = ET.parse('car.xml')
print(get_blinker(tree))
# off
flip_lights(tree)
print(get_blinker(tree))
# on
flip_lights(tree)
print(get_blinker(tree))
# off
flip_lights(tree)
print(get_blinker(tree))
# on
tree.write('car2.xml')
person unutbu    schedule 03.10.2010

Не говоря о достоинствах использования XML вместо модуля Python для управления файлами конфигурации, вот как сделать то, о чем вы просили, используя lxml:

>>> from lxml import etree
>>> xml = """<car>
   <lights>
      <blinkers>on</blinkers>
   </lights>
</car>"""
>>> doc = etree.fromstring(xml)
>>> elm = doc.xpath("/car/lights/blinkers")[0]
>>> elm.text="off"
>>> etree.tostring(doc)
'<car>\n   <lights>\n      <blinkers>off</blinkers>\n   </lights>\n</car>'
person Robert Rossney    schedule 03.10.2010

Взгляните на эту статью.

Но рассмотрите комментарий AaronMcSmooth выше - это может быть неправильный подход к вашей общей проблеме.

person bstpierre    schedule 03.10.2010

Используйте красивый каменный суп. Вот раздел по изменению xml:

http://www.crummy.com/software/BeautifulSoup/documentation.html#Modifying%20the%20Parse%20Tree

person amadain    schedule 03.10.2010