2012-07-04 34 views
3

我想從Pubmed下載一些XML - 沒有問題,Biopython是偉大的。問題是我不知道如何操作輸出。我想將大部分解析的xml放入sql數據庫中,但我對輸出不熟悉。對於某些事情,我可以像解析字典一樣調用解析的xml,但對其他人來說,它看起來並不那麼簡單。Biopython類實例 - 從Entrez.read輸出:我不知道如何操縱輸出

from Bio import Entrez 
Entrez.email="[email protected]" 
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 

但它不起作用。

乾杯

惠頓

回答

3

Entrez.read()方法是要回報你一個嵌套的數據結構,ListElement S和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源文件的最高層討論他motivations for representing the XML documents using the custom ListElements and DictionaryElements in Entrez

如果您非常好奇,您還可以閱讀源代碼中ListElement,DictionaryElementStructureElement類的迷人聲明。我會破壞這個驚喜,只是讓你知道它們對於基本的Python數據類型是非常輕鬆的包裝,並且其行爲與它們的基本數據類型幾乎完全相同,除了它們有一個新屬性attributes,它捕獲XML屬性(鍵和值)爲read解析的文檔中的每個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可以接受的輸出結果。如果您遇到問題,請隨時發佈另一個具體的問題。

+0

如何從您提供的示例中獲取屬性佔用情況? –

0

我不知道這是否是正確的,但我確實認爲,「記錄」是一個字典列表。所以,你需要得到每個字典使用循環

喜歡的東西

for r in record: 
    r['MedlineCitation'] 
+0

嗨Krishnik - 我想我的問題是:有沒有辦法使用class.object訪問數據的方式?和:我怎樣才能簡單地訪問StringElements,而不必首先通過str()來傳遞屬性? –

+0

另外,如何輕鬆訪問屬性?我可以抓取數據,但似乎是因爲有人花時間將這些數據全部以這種格式表達出來,所以必須有一種更簡單的方式來訪問它。 –

+1

不,使用Bio.Entrez中的Biopython XML解析器時,它沒有object.attribute樣式接口。您可能會更好地使用某個Python標準庫XML解析器直接執行某些任務 - 例如,在內部使用ElementTree - 取決於您喜歡的樣式。 Bio.Entrez中使用的基於句柄的API旨在允許這種模塊化 - 獲取數據與解析數據是分開的。 – peterjc