Я ищу синтаксический анализатор XML в словарь с помощью ElementTree, я уже нашел некоторые, но они исключают атрибуты, а в моем случае у меня много атрибутов.
Для преобразования XML из / в словари python xmltodict отлично сработал для меня:
import xmltodict
xml = '''
<root>
<e />
<e>text</e>
<e name="value" />
<e name="value">text</e>
<e> <a>text</a> <b>text</b> </e>
<e> <a>text</a> <a>text</a> </e>
<e> text <a>text</a> </e>
</root>
'''
xdict = xmltodict.parse(xml)
xdict теперь будет выглядеть как
OrderedDict([('root',
OrderedDict([('e',
[None,
'text',
OrderedDict([('@name', 'value')]),
OrderedDict([('@name', 'value'),
('#text', 'text')]),
OrderedDict([('a', 'text'), ('b', 'text')]),
OrderedDict([('a', ['text', 'text'])]),
OrderedDict([('a', 'text'),
('#text', 'text')])])]))])
Если ваш Данные XML не в виде необработанной строки / байтов, а в каком-то объекте ElementTree, вам просто нужно распечатать их в виде строки и снова использовать xmldict.parse. Например, если вы используете lxml для обработки документов XML, то
from lxml import etree
e = etree.XML(xml)
xmltodict.parse(etree.tostring(e))
создаст тот же словарь, что и выше.
Опираясь на @larsmans, если полученные ключи содержат информацию о пространстве имен xml, вы можете удалить ее перед записью в dict. Установите переменную xmlns
равной пространству имен и уберите ее значение.
xmlns = '{http://foo.namespaceinfo.com}'
def etree_to_dict(t):
if xmlns in t.tag:
t.tag = t.tag.lstrip(xmlns)
if d = {t.tag : map(etree_to_dict, t.iterchildren())}
d.update(('@' + k, v) for k, v in t.attrib.iteritems())
d['text'] = t.text
return d
Вы можете использовать этот фрагмент, который напрямую преобразует его из XML в словарь
import xml.etree.ElementTree as ET
xml = ('<xml>' +
'<first_name>Dean Christian</first_name>' +
'<middle_name>Christian</middle_name>' +
'<last_name>Armada</last_name>' +
'</xml>')
root = ET.fromstring(xml)
x = {x.tag: root.find(x.tag).text for x in root._children}
# returns {'first_name': 'Dean Christian', 'last_name': 'Armada', 'middle_name': 'Christian'}