ElementTree можно сказать сохранить порядок атрибутов?

Я записал довольно простой фильтр в использовании Python ElementTree к munge контексты некоторых XML-файлов. И это работает, более или менее.

Но это переупорядочивает атрибуты различных тегов, и я хотел бы, чтобы это не сделало это.

Кто-либо знает переключатель, который я могу бросить, чтобы заставить его сохранить их в указанном порядке?

Контекст для этого

Я работаю с и на инструменте физики элементарных частиц, который имеет комплекс, но странно ограниченную систему конфигурации на основе XML-файлов. Среди многой установки вещей тот путь пути к различным статическим файлам данных. Эти пути являются hardcoded в существующий xml и нет никаких средств для установки или варьирования их на основе переменных среды, и в нашей локальной установке они находятся обязательно в другом месте.

Это не авария, потому что объединенный источник - и инструмент управления сборки, который мы используем, позволяет нам теневым определенным файлам с локальными копиями. Но даже думал, что поля данных статичны, xml не, таким образом, я записал, что сценарий для фиксации путей, но с перестановкой атрибута diffs между локальными и основными версиями более тверды читать, чем необходимый.


Это - мой первый раз, беря ElementTree для вращения (и только мой пятый или шестой проект Python) поэтому, возможно, я просто делаю его неправильно.

Абстрагированный для простоты код похож на это:

tree = elementtree.ElementTree.parse(inputfile)
i = tree.getiterator()
for e in i:
    e.text = filter(e.text)
tree.write(outputfile)

Разумный или немой?


Связанные ссылки:

22
задан Community 23 May 2017 в 11:47
поделиться

3 ответа

Нет. ElementTree использует словарь для хранения значений атрибутов, поэтому он изначально неупорядочен.

Даже DOM не гарантирует упорядочение атрибутов, а DOM предоставляет гораздо больше деталей информационного набора XML, чем ElementTree. (Есть некоторые модели DOM, которые предлагают это как функцию, но это не стандартно.)

Можно ли это исправить? Может быть. Вот укол, заменяющий словарь при синтаксическом анализе упорядоченным ( collections.OrderedDict () ).

from xml.etree import ElementTree
from collections import OrderedDict
import StringIO

class OrderedXMLTreeBuilder(ElementTree.XMLTreeBuilder):
    def _start_list(self, tag, attrib_in):
        fixname = self._fixname
        tag = fixname(tag)
        attrib = OrderedDict()
        if attrib_in:
            for i in range(0, len(attrib_in), 2):
                attrib[fixname(attrib_in[i])] = self._fixtext(attrib_in[i+1])
        return self._target.start(tag, attrib)

>>> xmlf = StringIO.StringIO('<a b="c" d="e" f="g" j="k" h="i"/>')

>>> tree = ElementTree.ElementTree()
>>> root = tree.parse(xmlf, OrderedXMLTreeBuilder())
>>> root.attrib
OrderedDict([('b', 'c'), ('d', 'e'), ('f', 'g'), ('j', 'k'), ('h', 'i')])

Выглядит многообещающе.

>>> s = StringIO.StringIO()
>>> tree.write(s)
>>> s.getvalue()
'<a b="c" d="e" f="g" h="i" j="k" />'

Ба, сериализатор выводит их в каноническом порядке.

Это похоже на виноватую строку в ElementTree._write :

            items.sort() # lexical order

Создание подклассов или исправление обезьяны, которое будет раздражать, поскольку оно находится прямо в середине большого метода.

Если вы не сделали что-то неприятное, например подкласс OrderedDict и взломали элементы , чтобы вернуть специальный подкласс list , который игнорирует вызовы sort () . Нет, наверное, это еще хуже, и мне нужно лечь спать, прежде чем я приду к чему-нибудь более ужасному, чем это.

19
ответ дан 29 November 2019 в 03:43
поделиться

Неправильный вопрос. Должен быть: "Где найти гаджет diff, который разумно работает с XML файлами?"

Ответ: Google - ваш друг. Первый результат поиска по "xml diff" => this. Есть еще несколько вариантов.

5
ответ дан 29 November 2019 в 03:43
поделиться

Из раздела 3.1 рекомендации XML:

Обратите внимание, что порядок спецификаций атрибутов в теге start-tag или теге empty-element не имеет значения.

Любая система, которая полагается на порядок атрибутов в элементе XML, сломается.

3
ответ дан 29 November 2019 в 03:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: