Невозможно извлечь данные из файлов XML из-за различий в формате
У меня есть скрипт, который принимает кучу файлов XML, все в форме: HMDB61152.xml
и тянет их всех в использовании glob
, Для каждого файла мне нужно вытащить некоторые детали о каждом, такие как accession
, name
и список diseases
, Для разбора каждого XML я использовал xmltodict
потому что мне традиционно нравится работать со списками, а не с файлами XML, хотя, возможно, мне придется изменить свою стратегию из-за проблем, с которыми я сталкиваюсь.
Я могу тянуть name
а также acc
легко, поскольку все файлы XML имеют его на одном и том же первом уровне дерева:
пath = '/Users/me/Downloads/hmdb_metabolites'
for data_file in glob.glob(os.path.join(path,'*.xml')):
diseases=[]
with open(data_file) as fd:
doc = xmltodict.parse(fd.read())
name = doc['metabolite']['name']
acc = doc['metabolite']['accession']
Таким образом, на данный момент существует три варианта информации о заболевании:
- Есть несколько
disease
теги в каждомdiseases
дерево. Т.е. для данного вступления есть 2 или более заболеваний. - Есть один
disease
в пределахdiseases
дерево, означающее вступление, имеет только одну болезнь. или же - Нет
disease
вdiseases
дерево вообще.
Мне нужно написать цикл, который может обрабатывать любые три случая, и именно там я терплю неудачу. Вот мой подход до сих пор:
#I get the disease root, which returns True if it has lower level items (one or more disease within diseases)
#or False if there are no disease within diseases.
dis_root=doc['metabolite']['diseases']
if (bool(dis_root)==True):
dis_init = doc['metabolite']['diseases']['disease']
if (bool(doc['metabolite']['diseases']['disease'][0]) == True):
for x in range(0,len(dis_init)):
diseases.append(doc['metabolite']['diseases']['disease'][x]['name'])
else:
diseases.append(doc['metabolite']['diseases']['disease']['name'])
else:
diseases=['None']
Так что проблема в том случае, когда есть несколько заболеваний, мне нужно вытащить их имена в следующем формате: doc['metabolite']['diseases']['disease'][x]['name']
за каждый х при заболеваниях. Но для тех, у кого есть только одна болезнь, у них вообще нет индекса, поэтому единственный способ, которым я могу назвать название этой болезни, это сделать doc['metabolite']['diseases']['disease']['name']
,
Сценарий не выполняется, потому что, как только мы сталкиваемся со случаем только одной болезни, он возвращает KeyError, когда пытается проверить, doc['metabolite']['diseases']['disease'][0]) == True
, Если кто-то может помочь мне понять это, это было бы замечательно, или направить меня к более подходящей стратегии.
2 ответа
Попробуйте что-то вроде
if 0 in doc['metabolite']['diseases']['disease']:
pass # if 0 is a key in the array, we have multiple entries
else
pass # only a single item.
Нашел относительно легкий обходной путь, я просто использую try следующим образом:
try:
for x in range(0,len(dis_init)):
diseases.append(doc['metabolite']['diseases']['disease'][x]['name'])
except KeyError:
diseases.append(doc['metabolite']['diseases']['disease']['name'])