2014-11-15 1 views
1

Я использую ElementTree Python для создания XML-документа, и пока все хорошо. Однако проблема, с которой я столкнулся сейчас, заключается в том, что из-за требований к проекту мне нужно создать XML-документ с элементами с начальными и конечными тегами, а также с самозакрывающимися элементами тега. Мне нужно выводить пустые теги с тегами начала и конца, а также сохранять самозакрывающиеся элементы тега. Текущая реализация либо создает самозакрывающиеся теги, когда есть пустые элементы, и, таким образом, сохраняет самозакрывающиеся теги, это неверно из-за требований проекта. Кроме того, если я заставляю теги start/end для пустых элементов, самозакрывающиеся теги также преобразуются в элементы тега start/end, это тоже неверно.Отличия между <foo/> и <foo></foo> в Python Разбор и генерация XML

Может кто-нибудь, пожалуйста, помогите мне и назовите меня возможным решением, все приветствуются. Мне нужно использовать Python 2.7. Спасибо.

+1

Проблема заключается в том, что в отношении спецификации XML пустой тег означает то же самое, что и самозакрывающийся тег, поэтому маловероятно, что какая-либо универсальная библиотека XML будет делать то, что вы хотите (за исключением, может быть, случайно, и не документировано, чтобы продолжать работать именно так). Вероятно, вам придется зацепить или исправить один из них. Это может быть не слишком сложно, но это не будет тривиально. – abarnert

+2

Кто навязывает эти требования? Похоже, что кто-то написал плохой код, и это влияет на вас. Я бы объяснил моему начальнику, что ** официальный стандарт XML ** рассматривает их как эквивалентные, и потребитель должен сделать то же самое. Правильно, чтобы это было для того, кто нарушил потребление, чтобы исправить это; это будет намного лучше для проекта в долгосрочной перспективе, чем вы делаете свой код хуже, потому что их плохо. – jpmc26

+1

@ jpmc26 имеет право на это - если вы не исправляете код, который делает это различие, он будет головной болью каждый раз, когда вы вводите новый компонент, так как * каждый * стандартно-совместимый парсер/генератор ведет себя таким образом - как говорится в стандарте. Фактически, стандарт XML C14N определяет, что каноническая форма для любого XML-документа имеет пары пар начального конца, поэтому любое преобразование, которое выводится в канонической форме, теряет все кодированные данные, используя самозакрывающиеся теги. –

ответ

2

В качестве стандарта 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 в библиотеку, то Сопровождающие могут быть заинтересованы в принятии ваш патч вверх по течению.

+0

спасибо за указатели, заглянем в это, мне нужно это для работы, я вернусь сюда, если мне понадобится дополнительная поддержка. Конечно, если есть другие учебники/примеры, которые могут мне помочь, это было бы здорово, так как это был бы мой первый патч. – Francisco