我正在尝试从Pubmed下载一些xml - 没有问题,Biopython很棒。问题是我真的不知道如何操纵输出。我想将大部分已解析的xml放入sql数据库,但我不熟悉输出。对于某些事情,我可以将解析的xml称为字典,但对于其他人来说,它似乎并不是那么直接。
from Bio import Entrez
Entrez.email="xxxxxxxxxxxxx@gmail.com"
import sqlite3 as lite
handle=Entrez.efetch(db='pubmed',id='22737229', retmode='xml')
record = Entrez.read(handle)
如果我想找到标题,我可以这样做:
title=record[0]['MedlineCitation']['Article']['ArticleTitle']
但解析对象的类型是一个类:
>>> type(record)
<class 'Bio.Entrez.Parser.ListElement'>
>>>r=record[0]
>>>type(r)
<class 'Bio.Entrez.Parser.DictionaryElement'>
>>> r.keys()
[u'MedlineCitation', u'PubmedData']
这使得我认为必须有一种更简单的方法来做到这一点,而不是将其用作字典。但是当我尝试:
>>> r.MedlineCitation
Traceback (most recent call last):
File "<pyshell#67>", line 1, in <module>
r.MedlineCitation
AttributeError: 'DictionaryElement' object has no attribute 'MedlineCitation'
它不起作用。我显然可以将它用作字典,但后来我遇到了问题。
真正的问题是在使用字典时尝试从记录中获取某些信息:
>>> record[0]['MedlineCitation']['PMID']
StringElement('22737229', attributes={u'Version': u'1'})
这意味着我不能只是把它(这是一个技术术语;)放入我的sql数据库但需要转换它:
>>> t=record[0]['MedlineCitation']['PMID']
>>> t
StringElement('22737229', attributes={u'Version': u'1'})
>>> int(t)
22737229
>>> str(t)
'22737229'
总而言之,我很高兴Entrez.read()提供的信息深度,但我不确定如何轻松地使用生成的类实例中的信息。通常你可以做像
这样的事情record.MedlineCitation
但它不起作用。
干杯
惠顿
答案 0 :(得分:4)
Entrez.read()
方法将返回一个由ListElement
和DictionaryElement
组成的嵌套数据结构。有关更多信息,请查看read
method in the biopython source的文档,我将在下面摘录并解释:
def read(handle, validate=True):
This function parses an XML file created by NCBI's Entrez Utilities,
returning a multilevel data structure of Python lists and dictionaries.
...
the[se] data structure[s] seem to consist of generic Python lists,
dictionaries, strings, and so on, [but] each of these is actually a class
derived from the base type. This allows us to store the attributes
(if any) of each element in a dictionary my_element.attributes, and
the tag name in my_element.tag.
该软件包的作者Michiel de Hoon也花了一些时间在Parser.py
源文件的顶部,在Entrez
中讨论他的motivations for representing the XML documents using the custom ListElement
s and DictionaryElement
s。
如果您非常好奇,还可以阅读源中ListElement
,DictionaryElement
和StructureElement
类的精彩声明。我会破坏这个惊喜,让你知道它们是基本的Python数据类型的非常轻的包装器,并且它们的行为几乎与它们的基础基本数据类型完全相同,除了它们有一个新属性attributes
,它捕获read
正在解析的文档中每个XML节点的XML属性(键和值)。
所以你的问题的基本答案是没有“简单”的方法来使用点运算符语法来解决DictionaryElement
的键。如果你有一个字典元素d,那么:
>>> d
DictElement({'first_name': 'Russell', 'last_name': 'Jones'}, attributes={'occupation': 'entertainer'})
您可以阅读first_name
的唯一内置方法是使用普通的python词典API,例如:
>>> d['first_name']
'Russell'
>>> d.get('first_name')
'Russell'
>>> d.get('middle_name', 'No Middle Name')
'No Middle Name'
不要灰心,这真的不是那么糟糕。如果你想获取某些节点并将它们插入到sqlite数据库的行中,你可以编写以DictElement作为输入的小方法,并返回sqlite可以接受的输出。如果您遇到此问题,请随意发布另一个问题。
答案 1 :(得分:1)
我不确定这是否正确,但我相信这个记录是&#39;是一个词典列表。所以你需要使用循环来获取每个字典
像
这样的东西for r in record:
r['MedlineCitation']