Создание словаря из XML-файла

У меня есть и XML файл, который выглядит так:

 <?xml version="1.0" encoding ="utf8"?> <rebase> <Organism> <Name>Aminomonas paucivorans</Name> <Enzyme>M1.Apa12260I</Enzyme> <Motif>GGAGNNNNNGGC</Motif> <Enzyme>M2.Apa12260I</Enzyme> <Motif>GGAGNNNNNGGC</Motif> </Organism> <Organism> <Name>Bacillus cellulosilyticus</Name> <Enzyme>M1.BceNI</Enzyme> <Motif>CCCNNNNNCTC</Motif> <Enzyme>M2.BceNI</Enzyme> <Motif>CCCNNNNNCTC</Motif> </Organism> 

Для каждого Organism есть несколько Enzymes и Motifs . Ферменты уникальны, но мотивы могут повторяться. Поэтому я попытался создать словарь с ферментом в качестве ключа и мотива в качестве значения. Это мой код:

  import xml.etree.ElementTree as ET def lister(): tree = ET.parse('rebase.xml') rebase = tree.getroot() data_dict = {} for each_organism in rebase.findall('Organism'): try: enzyme = each_organism.find('Enzyme').text except AttributeError: continue for motif in each_organism.findall('Motif'): motif = motif.text data_dict[enzyme] = motif return data_dict 

Однако в словаре, кажется, опущено довольно много записей. Кажется, я понимаю, в чем проблема. Любая помощь будет оценена.

РЕДАКТИРОВАТЬ

Пользователь опубликовал решение, но затем удалил его, однако я мог скопировать его вовремя:

 for each_organism in rebase.findall('Organism'): try: enzyme = each_organism.find('Enzyme').text except AttributeError: continue data_dict[enzyme] = [] for motif in each_organism.findall('Motif'): data_dict[enzyme].append(motif.text) return data_dict 

Однако словари, возвращенные в этом случае, ошибочны, и почему:

Пара фермент-мотив уникален. Так что 1 фермент имеет только 1 мотив. Через мой файл фермент происходит только один раз, мотив может возникать несколько раз, но он относится к другому ферменту, поэтому пара уникальна. Что делает код под EDIT :

Предположим и фермент – M.APaI с мотивом GATC и еще один M.APaII с мотивом TCAG . Оба фермента довольно похожи (различаются только в последнем символе I ). Код связывает оба мотива с {M.ApaI :['GATC','TCAG']} ферментом, создающим {M.ApaI :['GATC','TCAG']}

One Solution collect form web for “Создание словаря из XML-файла”

Первая большая проблема, которую я вижу, заключается в том, что вы ищете только первый фермент в любом данном организме. Если вы хотите найти каждое заболевание фермента, вы должны использовать:

  for enzyme in each_organism.findall('Enzyme'): # add to dictionary here 

Вторая проблема заключается в том, что формат вашего XML не соответствует отношениям данных, которые вы, по-видимому, строите со своим словарем. В XML, Enzyme, Motif и Name все дети организма, но вы назначаете мотив в качестве значения, связанного с ключом фермента. Вы не можете знать, обязательно, когда повторяетесь через инциденты и которые должны быть связаны с другим, потому что все они застряли вместе без какого-либо логического разделения в объекте.

Я мог бы неправильно понять вашу цель здесь, но, похоже, вам будет лучше служить построение объектов класса Organism и Enzyme, а не принуждение двух (по-видимому) несвязанных понятий к отношениям «ключ-значение».

Это может выглядеть так и инкапсулировать ваши поля:

 class Organism: # where enzymes is an iterable of Enzyme def __init__(self, name, enzymes): self.name = name self.enzymes = enzymes 

и ваш объект фермента:

 class Enzyme: # where motifs is an iterable of string def __init__(self, motifs): self.motifs = motifs 

Все это по-прежнему потребует каких-либо изменений в вашем XML-файле. Если вы просто не разбираете его по строке (это явно не точка XML), я не могу придумать никаких простых способов, с помощью которых вы могли бы выяснить, какие мотивы принадлежат к тому, что Enzyme прямо сейчас.

Изменить: видя, как вы спрашиваете о том, как просто проследить до следа через каждый узел Enzyme и считая, что у вас всегда есть один элемент Name, у вас есть один Motif для каждого фермента, и каждый элемент после Name is Enzymes, а затем Motif ( например, EMEM и т. д.), вы должны иметь возможность сделать это:

 i = 0 enzymes = [] motifs = [] for element in each_organism: # skip the first Name child if i == 0: continue # if we're at an odd index, indicating an enzyme if i % 2 == 1: enzymes.append(element.text) # if we're at an even index, indicating the related motif elif i % 2 == 0: motifs.append(element.text) i += 1 

Затем, предполагая каждое допущение, которое я изложил, и, вероятно, еще пару (я даже не уверен, что на 100% всегда есть итерации элементов сверху вниз), верно, любой мотив при любом заданном индексе в мотивах будет принадлежать ферменту на тот же индекс в ферментах. Если я еще не прояснил это: это невероятно хрупкий код.

  • Проверка XML (.xsd) на схему
  • BeautifulSoup get_text не разделяет все теги и JavaScript
  • Удалить пространство имен и префикс из xml в python с помощью lxml
  • Почему XMLFeedSpider не выполняет итерацию через назначенные узлы?
  • Запуск памяти с использованием python ElementTree
  • В чем разница между cElementtree и ElementTree?
  • Обрезать некоторые элементы из большого xml-файла
  • Как использовать Xpath в Python?
  • Python - лучший язык программирования в мире.