Python: обновление XML-файла с использованием ElementTree при максимально возможном сохранении макета
У меня есть документ, который использует пространство имен XML, для которого я хочу увеличить/group/house/dogs
по одному: (файл называетсяhouses.xml
)
<?xml version="1.0"?>
<group xmlns="http://dogs.house.local">
<house>
<id>2821</id>
<dogs>2</dogs>
</house>
</group>
Мой текущий результат с использованием кода ниже: (созданный файл называетсяhouses2.xml
)
<ns0:group xmlns:ns0="http://dogs.house.local">
<ns0:house>
<ns0:id>2821</ns0:id>
<ns0:dogs>3</ns0:dogs>
</ns0:house>
</ns0:group>
Я хотел бы исправить две вещи (если это возможно с помощью ElementTree. Если это не так, я был бы рад предложению относительно того, что я должен использовать вместо этого):
Я хочу сохранить<?xml version="1.0"?>
линия.Я не хочу добавлять префиксы ко всем тегам, я хотел бы оставить все как есть.В заключение,Я не хочу связываться с документом больше, чем мне абсолютно необходимо.
Мой текущий код (который работает за исключением вышеупомянутых недостатков) генерирует приведенный выше результат следующим образом.
Я сделал служебную функцию, которая загружает XML-файл, используя ElementTree, и возвращает elementTree и пространство имен (поскольку я не хочу жестко кодировать пространство имен и готов пойти на риск, который он подразумевает):
def elementTreeRootAndNamespace(xml_file):
from xml.etree import ElementTree
import re
element_tree = ElementTree.parse(xml_file)
# Search for a namespace on the root tag
namespace_search = re.search('^({\S+})', element_tree.getroot().tag)
# Keep the namespace empty if none exists, if a namespace exists set
# namespace to {namespacename}
namespace = ''
if namespace_search:
namespace = namespace_search.group(1)
return element_tree, namespace
Это мой код для обновления количества собак и сохранения его в новом файлеhouses2.xml
:
elementTree, namespace = elementTreeRootAndNamespace('houses.xml')
# Insert the namespace before each tag when when finding current number of dogs,
# as ElementTree requires the namespace to be prefixed within {...} when a
# namespace is used in the document.
dogs = elementTree.find('{ns}house/{ns}dogs'.format(ns = namespace))
# Increase the number of dogs by one
dogs.text = str(int(dogs.text) + 1)
# Write the result to the new file houses2.xml.
elementTree.write('houses2.xml')