На этом шаге мы продолжим знакомиться с возможностями модуля xml.etree.ElementTree.
Вы хотите взять данные из словаря Python и превратить их в XML.
Хотя библиотека xml.etree.ElementTree обычно используется для парсинга, ее также можно применить для создания XML-документов. Например, посмотрите на такую функцию:
>>> from xml.etree.ElementTree import Element >>> def dict_to_xml(tag, d): ''' Превращает простой словарь пар ключ/значение в XML ''' elem = Element(tag) for key, val in d.items(): child = Element(key) child.text = str(val) elem.append(child) return elem
Вот пример ее работы:
>>> s = {'name': 'GOOG', 'shares': 100, 'price': 490.1}
>>> e = dict_to_xml('stock', s)
>>> e
<Element 'stock' at 0x0000028823F9B360>
>>>
Результатом этого преобразования является экземпляр Element. Для ввода-вывода его можно легко конвертировать в байтовую строку - для этого нужно использовать функцию tostring() из модуля xml.etree.ElementTree. Например:
>>> from xml.etree.ElementTree import tostring >>> tostring(e) b'<stock><name>GOOG</name><shares>100</shares><price>490.1</price></stock>' >>>
Если вы хотите прикрепить атрибуты к элементу, используйте метод set():
>>> e.set('_id', '1234') >>> tostring(e) b'<stock _id="1234"><name>GOOG</name><shares>100</shares><price>490.1</price></stock>' >>>
Если порядок элементов имеет значение, подумайте над созданием OrderedDict вместо обычного словаря.
При генерации XML вы можете склоняться к простому созданию строк. Например:
>>> def dict_to_xml_str(tag, d): ''' Превращает простой словарь пар ключ/значение в XML ''' parts = ['<{}>'.format(tag)] for key, val in d.items(): parts.append('<{0}>{1}</{0}>'.format(key,val)) parts.append('</{}>'.format(tag)) return ''.join(parts)
Проблема в том, что вы влезете в большие неприятности, если попытаетесь сделать это вручную. Например, что случится, если значения словаря будут содержать спецсимволы?
>>> d = {'name': '<spam>'}
>>> # Создание строки
>>> dict_to_xml_str('item', d)
'<item><name><spam></name></item>'
>>> # Правильное создание XML
>>> e = dict_to_xml('item', d)
>>> tostring(e)
b'<item><name><spam></name></item>'
>>>
Обратите внимание, как в последнем примере символы <and> заменяются на <and>.
Для справки: если вам когда-либо потребуется вручную экранировать или деэкранировать такие символы, вы можете использовать функции escape() и unescape() из модуля xml.sax.saxutils. Например:
>>> from xml.sax.saxutils import escape, unescape >>> escape('<spam>') '<spam>' >>> unescape(_) '<spam>' >>>
Если оставить в стороне создание правильного вывода, другая причина создавать экземпляры Element вместо строк заключается в том, что их легче объединять друг с другом для создания более крупного документа. Получающиеся экземпляры Element также могут быть обработаны различными способами без необходимости парсить XML-текст. Вы можете провести всю обработку данных высокоуровневым способом, а затем в самом конце вывести их в строковой форме.
На следующем шаге мы рассмотрим парсинг, изменение и перезапись XML.