ホーム > タグ > PORTA
PORTA
7月のPORTAリニューアルについて
- 2009年10月27日 7:02 PM
- 未分類
2009/7/7に「PORTA(国立国会図書館デジタルアーカイブポータル)」はリニューアルが行われ、外部提供インターフェイスにもいくつか機能が追加された(OpenSearchにISBNの前方一致検索を追加します)。もう随分前になってしまったが、気になるとこだけピックアップ。
OpenSearchにISBNの前方一致検索を追加
OpenSearchも、マッシュアップには一番使うであろうISBNによる検索に対応した。手軽に使えて、返ってくるメタデータも詳しい(ブラウザで表示するとあんまり見えないので、ソースを表示してみてください)。
- isbn=9784805208038 でNDL蔵書目録を検索
http://api.porta.ndl.go.jp/servicedp/opensearch?dpid=zomoku&isbn=9784805208038
SRU追加とCQL1.2対応
SRWのリクエストをREST(URLによるリクエスト)にしたSRUに対応した。SRWはSOAPを使うため、何かとめんどくさいが、SRUはURLに検索式を埋め込むので非常に楽。また検索式もCQL1.2に対応することで、検索クエリ中に並べ替えを指定することができるようになった。前の記事にいただいたコメントにもあるようにSRW/CQL1.1のsortKeysによる並べ替えは現時点でも実装されていないが、このCQL1.2による並べ替えはちゃんと実装されている。
- title = library でNDL蔵書目録を検索(タイトル昇順)
http://api.porta.ndl.go.jp/servicedp/SRUDp?operation=searchRetrive&maximumRecords=10&recordSchema=dcndl_porta&query=title+%3D+library+AND+dpid+%3D+zomoku+AND+sortBy+%3D%22title%2Fsort.ascending%22 - title = library でNDL蔵書目録を検索(タイトル降順)
http://api.porta.ndl.go.jp/servicedp/SRUDp?operation=searchRetrive&maximumRecords=10&recordSchema=dcndl_porta&query=title+%3D+library+AND+dpid+%3D+zomoku+AND+sortBy+%3D%22title%2Fsort.descending%22
OAI-PMHに対応
これ、ほんとにいいの?と思える大盤振る舞い。OAI-PMHは電子リソースのメタデータを網羅的に収集するためのプロトコル。より詳しくはWikipediaか国立情報学研究所によるドキュメントの和訳あたりを参照。ようは、PORTAが持ってるメタデータを網羅的にダウンロードできて、アップデートにもちゃんと対応できるわけで、これはかなり画期的。
- 2009-10-09にPORTAに登録されたNDL蔵書目録のコンテンツ
http://api.porta.ndl.go.jp/servicedp/oai2?verb=ListRecords&metadataPrefix=dcndl_porta&set=zomoku&from=2009-10-19&until=2009-10-19
このサンプルで返ってくるデータは一部で、末尾に書かれたtoken(resumptionToken要素に書かれている。なお、この要素のcompleteListSizeに検索式に対するレコードの全数が書かれている。この例では6971件)をパラメータにリクエストすることで、続きのデータを得られる。このときは、下記のようにverbとresumptionTokenだけを指定してリクエストする。
なお、日によってはものすごい膨大な量のデータを登録してるようなので、ハーベストしようと思ってる人は注意が必要。
itemnoによる検索に対応
これまではPORTAで特定の1つの書誌を取得したい場合は、ISBNなどを利用するしか無かったが、PORTAでのIDであるitemnoでの検索に対応した(SRW/SRUのみ)。実は2009/7/7時点ではこの機能が実装されてなかったので、PORTAの中の方に問い合わせを行ったところ、先日実装されたことをお伝えいただいた。ただし、データベース構造上、repositoryidを指定する必要があるらしく、repositoryidとitemnoを半角ハイフンでつないだものをitemnoとして指定することで、目的の情報を取得できる。IDで情報取得できるのは、マッシュアップにはよいですね。他の方法に比べて速いし。
PORTAのPHPサンプル数種。
- 2008年12月30日 12:35 AM
- 未分類
先日の記事(PORTAのAPI使ってみた、けど。)のあと、いろいろ試してようやくまともに書誌情報が取得できたので、報告します。
解説すると長くなるので、とりあえずPHPのサンプルを各種。プログラマー各氏にはこのほうが話が早いかも。
FC2ブログの仕様上、拡張子がphpだとアップ出来ないのでtxtにしてます。
PORTAへのリクエストでは、書誌情報のスキーマがdcかdcndl_portaか選べ、そのパッキング方法をxmlとstringから選べる。はじめどれがいいかわかんなかったので、都合この組み合わせ4つのサンプルを用意した。
- スキーマ:dc パッキング:xml
porta_dc_xml.txt - スキーマ:dc パッキング:string
porta_dc_string.txt - スキーマ:dcndl_porta パッキング:xml
porta_dcndl_xml.txt - スキーマ:dcndl_porta パッキング:string
porta_dcndl_string.txt
また、先日の記事の追記でも書いたけど、PHPのSimpleXMLだと名前空間の扱いがめんどくさいので、名前空間付きの要素名を適当に置換するバージョンも2つのスキーマ向けに作った。
- スキーマ:dc パッキング:xml 名前空間付きの要素名を置換
porta_dc_replace.txt - スキーマ:dcndl_porta パッキング:xml 名前空間付きの要素名を置換
porta_dcndl_replace.txt
結局、最後のやつが一番使いやすい気がします。
あと、おまけ。
- 最後のやつの出力サンプル
porta_dcndl_replace.html
にしても、dc:identifierの種類が属性を参照しないとわからんとか、全角英数字を使ってるとか、複数の著者名と役割表示が1つの文字列にまとめられてるとか、Amazonに比べると扱いにくいこと扱いにくいこと。既存の目録規則やDublin Coreにとらわれずに、もっとまともな構造のデータで出力してくれると嬉しいんだけどなあ。
PORTAのAPI使ってみた、けど。
- 2008年11月13日 6:31 PM
- 未分類
最近、更新してないなーと思ったので、いつもなら記事にしない程度(というか段階)の内容。
いま、蔵書管理のためのWebサービス(SocialtunesやLibraryThingみたいなやつだ)を試作してて、書誌情報をどこから取ろうかと考えた結果、amazonを主に、NDL(国立国会図書館)を補助として使うことに決めた。
NDLだけでは最新の図書の書誌情報が得られず、amazonには古い図書の情報が少ないというのが主な理由だ(ほかにもNDLにはシリーズやNDCなんかの情報があったり、書誌情報の信頼性・正確性が高いというのもある)。
もちろんWebcat/Webcat Plusも考えたが、APIとして公開しているものがなく、HTMLからの抽出は、処理の重さや信頼性、あとマナー的にもどうなのということで断念。はやくAPI作ってくださいな・・・。
WorldCatやLCも視野に入れたけど、労力の割にそれほどメリットもないので、今回は無視。NDLがWorldCatに情報提供してれば使ったかもなのになあ。
で、amazonのAPI(Amazon Associates Web Service)は超有名なだけあって、簡単に使えた。
PHPのサンプル探してたら、こちらのページがわかりやすかった。
- 週末プログラマのメモ帳:PHPでAmazon E-Commerce Service (ECS) 2
※こちらではクエリ文字列をrawurlencodeでエンコードしているが、うちの環境では必要なかった。
で、今度はNDLがやってる電子リソースポータル「PORTA」(今回はNDLの所蔵データベースしか使わないが)のAPIを使ってみた。※APIについてはPORTAの「このサイトについて」から「外部提供インタフェースについて」で見られる。なんでパーマリンクがないんじゃあ!
なんかSRU(Seach/Retrieval via URL;LCの作った検索プロトコル。URLでリクエストしてXMLでレスポンスがくる)はともかくSRW(SRUのリクエストがSOAP仕様のXMLになったやつ)の情報があまりにも少なくて、なんでSRUを採用しないのかちょっと理解に苦しむところではあるが、まあそれしかないんだから使うしか仕方ない。
で、以下のコードで、一応結果のオブジェクトは返ってくる。
<?php
$client = new SoapClient("http://api.porta.ndl.go.jp/servicedp/services/SRWDp?wsdl");
$q = '(title = architecture) AND (dpid ANY "zomoku zassaku okayama")';
$req = array('version' => '1.1', 'query' => $q,
'startRecord' => '1', 'maximumRecords' => '200',
'recordPacking' => 'string', 'recordSchema' => '',
'sortKeys' => 'title,,1');
$result = $client->searchRetrieveOperation($req);
print_r($result);
?>
しかし、返ってきたデータを見てみると、肝心の書誌情報が入っているrecordDataオブジェクトの中身がなぜか空。ヒット数とかはPORTAのWebで検索したときと同じなので、いいとこまでいってるとは思うんだけどなあ。
ちなみに渡すパラメータが足りないとエラー(java.lang.NullPointerException)が返ってくる。省略可能なのもあるし、仕様書で「設定されない場合」とかあるやつでも省略不能っぽいのもある。
ところで、このAPI、公開されてそこそこ日が経つけど、誰か使ってるんやろか。情報すくないんだよなあ。
ちなみに、今回、開発はWindows上でxamppを走らせてやってます。xamppはApache、PHP5、MySQLやらが一気に使えて(しかもPortable)たいへん便利。ただ、ドライブのルートに配置しないといかんという制限があるので、仮想ドライブを指定するコマンドを書いた、下記のバッチファイルを作ってxammpディレクトリと同じディレクトリに置いて、開発時に実行してます。
rem connect current directory to x: drive
subst x: "%cd%"
exit
追記(2008/12/17)
さっき、この追記を書き終えたところで、さあ更新しようと思って、フォームからフォーカス外すために適当なとこクリックしたら、ちょうどそこがリンクになってて、追記分まるまる消えましたよ・・・。もうやる気ないんで、雑な書き方で。箇条書きって楽だなあ。
- PHPが原因じゃないかとC#で試すもWeb参照でエラー。なんでや。
- soapUIを発見。試してみるとrecordDataにデータ入ってる!
- どうもrecordDataは<!CDATA[[]]>に囲まれて返ってくる模様。
- PHPのSoapClientがレスポンスXMLを配列にする時に落ちてるんかな(参考:xml_parse_into_structを使うと、xmlの中のCDATAが消える -OKWave)。
- ということは、これが落ちないようにするか、配列にする前のXMLをそのまま取得できればOK。
- 後者ならsimplexml_load_stringでLIBXML_NOCDATAオプション指定で配列に変換。
まだ最後に書いた解決策のどちらも見つけられてないんですが、また、進展があれば、書きます。
新しく記事起こした場合はこの記事にトラックバックしときます。
追記(2008/12/27)
進展があったのでご報告。ようやく書誌情報にアクセス出来ました。
まず、前の追記に書いていた、配列にする前のXMLを取得する方法がわかった。
SoapClient->__getResponseで最後のレスポンスを文字列で取得できる。てっきりこれも配列で返ってくると思ってたよ。
上のコードの例だと、$client->searchRetrieveOperation($req);のあとに、
$xmlstr = $client->__getRenponse();
で、レスポンスXMLを文字列として取得できる。
こいつをsimplexml_load_stringでCDATAをテキストノードに展開しつつ、配列に変換する。(参考:SimpleXMLでCDATAを取得したいときはLIBXML_NOCDATAを使う – F.Ko-Jiの「一秒後は未来」)
$r = simplexml_load_string($xmlstr, 'SimpleXMLElement', LIBXML_NOCDATA);
これをprint_rで見てみると、
SimpleXMLElement Object ()
あれ?パースエラーかなーなどといろいろ調べてみると、パース自体はできてるけど、ルート要素と名前空間が違う(あるいは名前空間が指定されてる)要素は、SimpleXMLElement->children()で名前空間のURIを指定してアクセスしないといかんらしい。(参考:.☆★ ステレオタイプラボ ★☆. [php]simplexml_load_fileでうまくパース出来ない、なんて事はない。& 正解とお手軽方法)
名前空間を指定する:を別の文字に置換しちゃうという手も魅力的だけど、まあ正攻法でやってみる。
先ほどの$xmlstrをprint_rで見てみると、こんな構成になってる。
<soapenv:envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:body>
<searchretrieveresponse xmlns="http://www.loc.gov/zing/srw/">
(レスポンスされたデータ本体)
</searchretrieveresponse>
</soapenv:body>
</soapenv:envelope>
よって以下のコードでsearchretrieveresponseにアクセスする。
$srr = $r->children('http://schemas.xmlsoap.org/soap/envelope/')->Body->children('http://www.loc.gov/zing/srw/');
これですべてのレコードにアクセスできるが、個々の書誌情報がはいってるrecordData要素には、書誌情報のXMLがCDATAとして入ってる。このままだとアクセスしにくいので、これも配列に変換する。例では1つめのレコードの書誌情報をrdに入れている。今回はLIBXML_NOCDATAは(たぶん)いらない。
$rd = simplexml_load_string($srr->searchRetrieveResponse->records->record[0]->recordData[0]);
で、さらにこの中身はルート要素と名前空間が違うので・・・
$dc = $rd->children('http://purl.org/dc/elements/1.1/');
で、ようやく書誌情報にまともにアクセスできます。めんどくせー!
で、上記の方法で取得してみたデータのサンプル。(クエリは$q = ‘(isbn = 4000074628) AND (dpid ANY “zomoku”)’;に変えてる)
SimpleXMLElement Object
(
[title] => クマムシ?! : 小さな怪物
[creator] => 鈴木忠‖著
[description] => Array
(
[0] => 本体価格 : 1300円
[1] => シリーズよみ : イワナミ カガク ライブラリー ; 122
[2] => シリーズ : 岩波科学ライブラリー ; 122
[3] => 形態 : 112p ; 19cm
[4] => 出版地 : 東京
)
[publisher] => 岩波書店
)
ほとんどdescriptionにフィールド名とデータをまとめていれちゃってるという、なめてんのかってデータですね(スキーマがdcだからか?また追って調べます。今日はもう疲れた。)。
ホーム > タグ > PORTA
- 検索
- フィード
- メタ情報
