PubMed IDから論文のリストを作ろう(実装編 その1)
##経緯(復習)
研究室の論文管理が煩雑なので,PubMedから情報を収集するフォーマットと,それを簡単に編集できるプログラムを書いたらいいんじゃない?と思い,ちょいと取り組んで見ることにした。すると素晴らしきNCBIはPubMed IDをアドレスに指定すると,xmlで返してくれることを知った。PubMed IDから論文のリストを作ろう(調査編)
NCBI:国立生物工学情報センター(こくりつせいぶつこうがくじょうほうセンター、英: National Center for Biotechnology Information、NCBI)は、アメリカ合衆国の国立衛生研究所 (NIH) の下の国立医学図書館 (National Library of Medicine; NLM) の一部門として 1988年11月4日に設立された機関。
##何で実装しようか。
###JavaScriptにしよっ♡
結局ウェブ上で公開したいので,JavaScriptじゃにゃい?という単純な発想なもと(簡単なプログラムはRubyで書くのでRuby on Railsも頭を掠めたがやったことないので,今はやめとくことにした。)調べることに。
###なんだかんだ言って良質な情報はまだ本の中にあることが多いんじゃない?
いや,ネット上にもあるかもしれないのだけど,まとまるという意味では本のほうが良いなぁと思うことがしばしば。Anyway,手元にあった本を読み返すとあったあった,xml解析。よくわかるJavaScriptの教科書
まるっと中身を見たり,実行してみたいときは,[こちら]
↑今年度からぼちぼち学習しましたが,とても分かりやすい良い本だと思います。
(http://book.mycom.co.jp/support/pc/js/)からサンプルファイルをダウンロードし,js_samples/part03/lecture2-10/index.html (とrss.xml)を動かしてみると良いと思います。
参考になりそうなコードがあったので,一部抜粋します。
*注意:こちらの環境要因かもしれないのですが,ローカルで(サーバー上ではOKでした)は何故か,Chromeで動かなかったので,お試しの際は他のブラウザで試してみてください。
ちなみにFirefox使いの方は,JavaScriptのエラーチェック等にFirebugもオススメです。
取り出したいもとのrssがこんなかんじだったとする。
<rss ...>
<channel>
<title>H2O Space. - エイチツーオー・スペース | ちゃんとWeb</title>
...
<item>
<title>【12/19】ロクナナワークショップ主催『集中特訓!スマートフォンサイト制作術』に出演いたします</title>
<link>http://h2o-space.com/news/152/</link>
<comments>http://h2o-space.com/news/152/#comments</comments>
<pubDate>Tue, 13 Dec 2011 05:01:01 +0000</pubDate>
<dc:creator>h2ospace</dc:creator>
<category>
<![CDATA[ ニュース ]]>
</category>
<guid isPermaLink="false">http://h2o-space.com/?p=152</guid>
<description>
<![CDATA[
2011年 12月 19日に開催される、...
]]>
</description>
<content:encoded>
<![CDATA[
<p>2011年 12月 19日に開催される、ロクナナ...
]]>
</content:encoded>
<wfw:commentRss>http://h2o-space.com/news/152/feed/</wfw:commentRss>
<slash:comments>0</slash:comments>
</item>
上記のrssの情報を取ってくるjavascript(html内)のサンプルプログラム
<h2>News</h2>
<div id="news">Now loading... (If you cannot see this page,
Please refer to this <a href="news.html">link</a>.
</div>
…
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
$.ajax({
url:'rss.xml',//読み出すURL
dataType:'xml',//受信するデータの種類
async:true,//非同期通信*を有効にするか
success:function(xml){
var html='';//変数
$(xml).find('channel item').each(function(){
html += '<li><a href="' + $(this).find('link').text() + '">' + $(this).find('title').text() + '</a></li>';
});
$('#news').html('<ul>' + html + '</ul>');
},
error: function(html){
alert('Fell the data loading, Please access later');
}
});
</script>
*非同期通信とは、データの通信に際して送信側と受信側で厳密にクロック周波数や位相を一致させないで通信する方式のことである。送信者と受信者の両方がオンラインである必要がなく、片方が接続しているだけで通信が成立する。出典:IT用語辞典バイナリ
最初に<div id="news">…</div>
で囲んでidを指定します。
次にJavaScriptの中身ですが,xmlからデータを得られたら,そこの構造に従って,channel以下のitem要素がたくさんあるので,それをループで取り出します。htmlと変数を設定して,取り出したitem以下にあるlinkとtitleをそれぞれ探し出し,テキストで吐き出し,htmlとして出力できる形に整えています。$('#news').html('<ul>' + html + '</ul>');
で先ほど指定したid要素に,変数htmlに入れた内容を取り出し,'<ul>' + html + '</ul>'
と整えて取り出してあげます。
そうすると,こんな感じでrss.xmlからデータを取得し,表示できます。
さあこれを利用してみよう。
まず,PubMedから取得したxmlを再度見よう。レッツアクセス。
PubMedから取得したxml例
大体できたぞなもし。関係部分だけ抜粋。多分htmlの中に入れてあげれば動くはず。
<div id="contents">
<div class="inner">
<h2>Publication Lists</h2>
<div id="news">Now loading... (If you cannot see this page,
Please refer to this <a href="news.html">link</a>.
</div>
</div>
</div>
<!-- inner --></div>
<!-- contents --></div>
<footer>
<small><img src="../../_shared/img/footer_copy.png" width="147" height="14" alt="(C)H2O Space. Mynavi"></small>
<!-- footer --></footer>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
$.ajax({
url:'http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&id=22674858,22434880',//読み出すURL
dataType:'xml',//受信するデータの種類
async:true,//非同期通信を有効にするか
success:function(xml){
var html='';
$(xml).find('DocSum').each(function(){//DocSumが1つの論文
var title = $(this).find('Item').filter('[Name^=Title]').text();
var PubDate = $(this).find('Item').filter('[Name^=PubDate]').text();
var pubmed = $(this).find('Item').filter('[Name^=pubmed][Type^=String]').text();
//子ノードがないないものはfilterをかけて属性ごとに取得。
var authorlist = '';//子ノードがあるものは中身をみる。
$(this).find('Item').filter('[Name^=AuthorList]').each(function(){
var authornum = $(this).find('Item').length;//著者数を数えて
for(var i = 0; i < authornum;i++){
var author = $(this).find('Item').eq(i).text();
authorlist += author + '.,';//リストに加えていく。
}
});
html += '<li>' + authorlist +' '+ title + ', ' + PubDate + ', ' + '<a href="http://www.ncbi.nlm.nih.gov/pubmed/'+pubmed + '">PubMed:'+pubmed+'</a></li>';
//1つ追記。せっかくなのでPubMedのリンクも入れたよ。
});
$('#news').html('<ul>' + html + '</ul>');//全て追加した所で<div id="news">内に取得
},
error: function(html){
alert('Fell the data loading, Please access later');
}
});
</script>
解説はスクリプト中をみてちょ。
xml解析で見てたら属性で絞り込みをするということにいきつくまで大変時間がかかりましたが(半日くらい(^_^;))一応出来ました。
ただ,もっと良さげな書き方がある気がするので,思いついたら教えて下さい。
こんなかんじで出力出来ました。次回はインターフェイスを作り,そこからの入力を受け取って出力できるようにしたいと思います。