2012-01-12 3 views
1

Я использую cElementTree для извлечения тегов и значений XML в цикле, а затем их хранения в словаре.Загрузка различных типов данных из XML в словарь в python

XML-файл содержит:

<root> 
    <tag1>['item1', 'item2']</tag1> 
    <tag2>a normal string</tag2> 
</root> 

код Python (примерно):

import xml.etree.cElementTree as xml 

xmldata = {} 
xmlfile = xml.parse(XMLFile.xml) 
for xmltag in xmlfile.iter(): 
    xmldata[xmltag.tag] = xmltag.text 

Проблема я столкнулся в том, что файл XML содержит различные типы данных, которые включают в себя string и list. К сожалению, Element.text сохраняет все значения xml как string (включая списки).

Так что, когда я загружаю из файла XML у меня есть:

{'tag1':"['item1', 'item2']", 'tag2':'a normal string'} 

Когда я предпочел бы иметь:

{'tag1':['item1', 'item2'], 'tag2':'a normal string'} 

Есть простой способ сделать это?
например команда, которая сохраняет в словарь в оригинальном формате

Или мне нужно установить, если оператор для определения типа значения и сохранить его отдельно, используя альтернативу Element.text?

+0

Не могли бы вы включить полный фрагмент кода, включая значение xmldata, чтобы мы могли воспроизвести проблему? –

+0

@DavidRobinson Обновлены. – user788462

+0

Возможно, вы могли использовать 'eval', за исключением того, что ваши строки не окружены' '' в XML. –

ответ

1

Вы можете использовать literal_eval, чтобы попытаться разобрать сложные питона литералов. Поскольку ваши strigns являются неупомянуты, они поднимут SyntaxError в lteral Eval, но это simle работать вокруг:

import xml.etree.cElementTree as xml 
from ast import literal_eval 

xmldata = {} 
xmlfile = xml.parse(XMLFile.xml) 
for xmltag in xmlfile.iter(): 
    try: 
     xmldata[xmltag.tag] = literal_eval(xmltag.text) 
    except SyntaxError: 
     xmldata[xmltag.tag] = xmltag.text 

В отличии от встроенной команды Пайтона «Eval», ast.literal_eval не допускает выполнение выражений, и, таким образом, является безопасным, даже если данные XML поступают из ненадежного источника.

+0

Спасибо, это удобно знать. – user788462

1

Предлагаемое решение: проверить наличие [, затем разобрать список. Это не безопасно (это не сработает, если разделитель не точно , с пробелом), но я думаю, что вам будет легко его улучшить.

import xml.etree.cElementTree as xml 

xmldata = {} 
xmlfile = xml.parse("data.xml") 
for xmltag in xmlfile.iter(): 
    # it's a list 
    if "[" in xmltag.text: 
     d = xmltag.text.lstrip("[").rstrip("]") 
     l = [item.lstrip("'").rstrip("'") for item in d.split(", ")] 
     xmldata[xmltag.tag] = l 
    else: 
     xmldata[xmltag.tag] = xmltag.text 

print xmldata 

Печать: {'root': '\n', 'tag1': ['item1', 'item2'], 'tag2': 'a normal string'}

1

Я думаю, что вы не используете xml во всей своей могучей власти!

Почему вы не упорядочивания .xml как:

<root> 
    <tag1> 
     <item>item1</item> 
     <item>item2</item> 
    </tag1> 
    <tag2>a normal string<tag2> 
</root> 

Таким образом, ваш код питона будет заниматься каждый <tag1> как контейнер <item>, и я думаю, что это лучше.

Примечание: Вы также можете посмотреть here. (Я согласен с «Любимым способом» автора)

+0

Спасибо, Рик, приятно знать, что я на правильном пути, используя элементы :) – user788462

Смежные вопросы