В качестве стандарта XML пустой тег означает то же самое, что и самозакрывающийся тег.
Итак, во-первых, это, вероятно, не очень хорошая идея.
И, во-вторых, большинство библиотек XML, вероятно, не позволят вам различать эти два.
Но если вам нужно это сделать, вы всегда можете исправить любую библиотеку, которую хотите. Поскольку вы уже используете ElementTree
, это кажется очевидным выбором для исправления.
В последних версиях ElementTree
(включая версию, которая поставляется с Python 3.4+, но в старых питонах вам необходимо установить последнюю версию внешне поддерживаются версии), вы можете контролировать это глобально , с аргументом short_empty_elements
до write
и связанными с ним функциями. Но, как вы говорите, это не то, что вы на самом деле хотите; вам нужно, чтобы некоторые элементы были самозакрывающимися, а некоторые нет.
Я думаю, вам будет лучше начать с версии, поддерживаемой извне, ElementTree
, а не версии, встроенной в Python 2.7. Но я не уверен, где его официальное репо, поэтому я буду ссылаться на код Python 3.4. Надеюсь, это даст вам достаточно, чтобы взять его оттуда.
Ключевая функция serialize_xml
. I думаю,, что функция не C-ускорена, поэтому вам нужно только изменить чистую версию Python. В этом случае это только одна строка:
if text or len(elem) or not short_empty_elements:
Изменить это:
if text or len(elem) or not getattr(elem, 'short_empty', short_empty_elements):
И теперь, если вы установите node.short_empty = True
или node.short_empty = False
на пустом узле, он будет переопределять глобальные параметры для short_empty_elements
.
За исключением ... Я думаю, что если вы используете C ускоритель, вы не можете добавлять атрибуты (я имею в виду атрибуты Python, как node.short_empty
, а не XML атрибуты) на Element
. Это означает, что вам нужно либо заплатить Element
, чтобы разрешить это (что is partly in C - вам не нужно отключать __dict__
и изменить else
, чтобы позвонить PyObject_GenericSetAttr
вместо рейза), или подделать его, например., используя некоторый фальшивый атрибут XML, который вы снимаете при сериализации.
Конечно, если вы используете ElementTree
, а не cElementTree
в 2.7, вы не используете ускоритель C, поэтому вам, вероятно, не нужно беспокоиться об этой части.
Вы можете рассмотреть глядя на lxml
реализации ElementTree
API, чтобы увидеть, если это легче исправить.
Между тем, учитывая, что они добавили short_empty_elements
в библиотеку, то Сопровождающие могут быть заинтересованы в принятии ваш патч вверх по течению.
Проблема заключается в том, что в отношении спецификации XML пустой тег означает то же самое, что и самозакрывающийся тег, поэтому маловероятно, что какая-либо универсальная библиотека XML будет делать то, что вы хотите (за исключением, может быть, случайно, и не документировано, чтобы продолжать работать именно так). Вероятно, вам придется зацепить или исправить один из них. Это может быть не слишком сложно, но это не будет тривиально. – abarnert
Кто навязывает эти требования? Похоже, что кто-то написал плохой код, и это влияет на вас. Я бы объяснил моему начальнику, что ** официальный стандарт XML ** рассматривает их как эквивалентные, и потребитель должен сделать то же самое. Правильно, чтобы это было для того, кто нарушил потребление, чтобы исправить это; это будет намного лучше для проекта в долгосрочной перспективе, чем вы делаете свой код хуже, потому что их плохо. – jpmc26
@ jpmc26 имеет право на это - если вы не исправляете код, который делает это различие, он будет головной болью каждый раз, когда вы вводите новый компонент, так как * каждый * стандартно-совместимый парсер/генератор ведет себя таким образом - как говорится в стандарте. Фактически, стандарт XML C14N определяет, что каноническая форма для любого XML-документа имеет пары пар начального конца, поэтому любое преобразование, которое выводится в канонической форме, теряет все кодированные данные, используя самозакрывающиеся теги. –