# -*- coding: utf-8 -*- try: from lxml import etree except ImportError: from xml.etree import ElementTree as etree # Можно завести словарь, который содержит имена таблиц REALTY_TYPE_TABLE_NAMES = { 'Apartment': 'apartment', 'House': 'house', 'Nonlive': 'office', 'Land': 'stead' } # Поля. которые нужно достать REQUIRED_PROPERTIES = ['district', 'street', 'price', 'level', 'area_all', 'object_details', 'info'] # Получаем имя таблицы путём склейки строки. В принципе, можно и через if это делать def get_table_name(obj_type, obj_realty_type): return '_'.join(('maklers', obj_type.lower(), REALTY_TYPE_TABLE_NAMES.get(obj_realty_type, 'unknown'))) def parse(filename): result = list() tree = etree.parse(filename) root = tree.getroot() # Корневой элемент содержит список объектов, пробегаем по всем его дочерним элементам for obj in root: data = dict() # Всегда проверяем правильность в том месте, где получаем элементы try: # Аттрибуты xml хранятся в поле 'attrib' в виде словаря data['oid'] = obj.attrib['oid'] except KeyError: raise etree.ParseError('Неверный формат xml') # Получаем дочерний элемент с именем тэга 'object_property' prop = obj.find('object_property') if prop is None: raise etree.ParseError('Неверный формат xml') try: # Записываем в 1 переменную 2 значения (они будут в виде списка) obj_types = prop.attrib['type'], prop.attrib['realty_type'] except KeyError: raise etree.ParseError('Неверный формат xml') # Разворачиваем список, чтобы передать в функцию data['table_name'] = get_table_name(*obj_types) try: # Пытаемся получить значения всех необходимых атрибутов for attr_name in REQUIRED_PROPERTIES: data[attr_name] = prop.attrib[attr_name] except KeyError: raise etree.ParseError('Неверный формат xml') # Если позволительно некоторые атрибуты опустить, то можно сделать немного по-другому: # # for attr_name, attr_value in prop.attrib.items() # if attr_name in REQUIRED_PROPERTIES: # data[attr_name] = attr_value # Добавляем текущие данные в список result.append(data) # Хотя лучше возвращать генератор: # В конце цикла написать `yield data` # И убрать в конце функции `return result` # # В основной программе работать с генератором только через for (и другие штуки для итераторов) # ибо генератор не хранит все данные. # Генератор стоит использовать, если данные нужны только 1 раз (например, чтобы их в БД засунуть) return result if __name__ == '__main__': for obj in parse('document.xml'): print(obj)