Конвертировать XML в словарь

1

Мне нужно преобразовать XML файл в словарь (позже он будет преобразован в JSON).

Пример XML-скрипта выглядит так:

<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="Overpass API 0.7.55.3 9da5e7ae">
<note>The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.</note>
<meta osm_base="2018-06-17T15:31:02Z"/>
...
  <node id="2188497873" lat="52.5053306" lon="13.4360114">
    <tag k="alt_name" v="Spreebalkon"/>
    <tag k="name" v="Brommybalkon"/>
    <tag k="tourism" v="viewpoint"/>
    <tag k="wheelchair" v="yes"/>
  </node>
...
</osm>

С помощью простого кода я уже отфильтровал все значения, которые мне нужны для моего словаря:

Код

import xml.etree.ElementTree as ET

input_file = r"D:\berlin\trial_xml\berlin_viewpoint_locations.xml"

tree = ET.parse(input_file)
root = tree.getroot()

lst1 = tree.findall("./node")
for item1 in lst1:
    print('id:',item1.get('id'))
    print('lat:',item1.get('lat'))
    print('lon:',item1.get('lon'))
    for item1_tags_and_nd in item1.iter('tag'):
        print(item1_tags_and_nd.get('k') + ":", item1_tags_and_nd.get('v'))

Результат

id: 2188497873
lat: 52.5053306
lon: 13.4360114
alt_name: Spreebalkon
name: Brommybalkon
tourism: viewpoint
wheelchair: yes

Можете ли вы мне помочь, пожалуйста, правильно и эффективно добавить эти значения в словарь?

Я хочу, чтобы это выглядело так:

{'id': '2188497873', 'lat': 52.5053306, 'lon': 13.4360114, 'alt_name': 'Spreebalkon', 'name': 'Brommybalkon', 'tourism': 'viewpoint', 'wheelchair': 'yes'}

Я пробовал с

dictionary = {}
dictionary['id'] = []
dictionary['lat'] = []
dictionary['lon'] = []
lst1 = tree.findall("./node")
for item1 in lst1:
    dictionary['id'].append(item1.get('id'))
    dictionary['lat'].append(item1.get('lat'))
    dictionary['lon'].append(item1.get('lon'))
    for item1_tags_and_nd in item1.iter('tag'):
       dictionary[item1_tags_and_nd.get('k')] = item1_tags_and_nd.get('v')

но пока это не работает.

  • 0
    То есть есть только один <node> ?
  • 0
    Виллем , нет, я просто пропустил все остальные, чтобы иметь возможность продемонстрировать на одном примере.
Показать ещё 1 комментарий
Теги:
dictionary

1 ответ

2
Лучший ответ

Я предлагаю вам создать список dicts, а не диктовать списки, например:

result_list = []
for item in tree.findall("./node"):
    dictionary = {}
    dictionary['id'] = item.get('id')
    dictionary['lat'] = item.get('lat')
    dictionary['lon'] = item.get('lon')
    result_list.append(dictionary)

Или как пара понятий вроде:

result_list = [{k: item.get(k) for k in ('id', 'lat', 'lon')}
               for item in tree.findall("./node")]

И для вложенного случая:

result_list = [{k: (item.get(k) if k != 'tags' else
                    {i.get('k'): i.get('v') for i in item.iter('tag')})
                for k in ('id', 'lat', 'lon', 'tags')}
               for item in tree.findall("./node")]

Результаты:

{
    'id': '2188497873', 
    'lat': '52.5053306', 
    'lon': '13.4360114', 
    'tags': {
         'alt_name': 'Spreebalkon', 
         'name': 'Brommybalkon', 
         'tourism': 'viewpoint', 
         'wheelchair': 'yes'
    }
}
  • 0
    Уважаемый мистер Раух, можете ли вы быть так добры и объяснить мне: 1) Как я могу справиться со своим вложенным циклом? 2) Как вы сделали свой код таким умным и гармоничным?
  • 0
    @TarasDubrava, я добавил немного для вложенного цикла. Что касается того, как сделать так, чтобы это выглядело гармонично, я предлагаю вам взглянуть на ссылку для понимания списка. В примерах есть как понимание списка, так и диктата, но как только вы поймете понимание списка, понимание диктата будет примерно одинаковым. И если вы хотите сгладить противоречие, которое я показываю в результатах, есть способы сделать это, я бы предложил поискать в Stackoverflow.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню