ホーム > タグ > PORTA

PORTA

7月のPORTAリニューアルについて

2009/7/7に「PORTA(国立国会図書館デジタルアーカイブポータル)」はリニューアルが行われ、外部提供インターフェイスにもいくつか機能が追加された(OpenSearchにISBNの前方一致検索を追加します)。もう随分前になってしまったが、気になるとこだけピックアップ。

OpenSearchにISBNの前方一致検索を追加

OpenSearchも、マッシュアップには一番使うであろうISBNによる検索に対応した。手軽に使えて、返ってくるメタデータも詳しい(ブラウザで表示するとあんまり見えないので、ソースを表示してみてください)。

SRU追加とCQL1.2対応

SRWのリクエストをREST(URLによるリクエスト)にしたSRUに対応した。SRWはSOAPを使うため、何かとめんどくさいが、SRUはURLに検索式を埋め込むので非常に楽。また検索式もCQL1.2に対応することで、検索クエリ中に並べ替えを指定することができるようになった。前の記事にいただいたコメントにもあるようにSRW/CQL1.1のsortKeysによる並べ替えは現時点でも実装されていないが、このCQL1.2による並べ替えはちゃんと実装されている。

OAI-PMHに対応

これ、ほんとにいいの?と思える大盤振る舞い。OAI-PMHは電子リソースのメタデータを網羅的に収集するためのプロトコル。より詳しくはWikipedia国立情報学研究所によるドキュメントの和訳あたりを参照。ようは、PORTAが持ってるメタデータを網羅的にダウンロードできて、アップデートにもちゃんと対応できるわけで、これはかなり画期的。

このサンプルで返ってくるデータは一部で、末尾に書かれた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サンプル数種。

先日の記事(PORTAのAPI使ってみた、けど。)のあと、いろいろ試してようやくまともに書誌情報が取得できたので、報告します。

解説すると長くなるので、とりあえずPHPのサンプルを各種。プログラマー各氏にはこのほうが話が早いかも。

FC2ブログの仕様上、拡張子がphpだとアップ出来ないのでtxtにしてます。

PORTAへのリクエストでは、書誌情報のスキーマがdcかdcndl_portaか選べ、そのパッキング方法をxmlとstringから選べる。はじめどれがいいかわかんなかったので、都合この組み合わせ4つのサンプルを用意した。

また、先日の記事の追記でも書いたけど、PHPのSimpleXMLだと名前空間の扱いがめんどくさいので、名前空間付きの要素名を適当に置換するバージョンも2つのスキーマ向けに作った。

結局、最後のやつが一番使いやすい気がします。

あと、おまけ。

にしても、dc:identifierの種類が属性を参照しないとわからんとか、全角英数字を使ってるとか、複数の著者名と役割表示が1つの文字列にまとめられてるとか、Amazonに比べると扱いにくいこと扱いにくいこと。既存の目録規則やDublin Coreにとらわれずに、もっとまともな構造のデータで出力してくれると嬉しいんだけどなあ。

PORTAのAPI使ってみた、けど。

最近、更新してないなーと思ったので、いつもなら記事にしない程度(というか段階)の内容。

いま、蔵書管理のためのWebサービス(SocialtunesLibraryThingみたいなやつだ)を試作してて、書誌情報をどこから取ろうかと考えた結果、amazonを主に、NDL(国立国会図書館)を補助として使うことに決めた。

NDLだけでは最新の図書の書誌情報が得られず、amazonには古い図書の情報が少ないというのが主な理由だ(ほかにもNDLにはシリーズやNDCなんかの情報があったり、書誌情報の信頼性・正確性が高いというのもある)。

もちろんWebcat/Webcat Plusも考えたが、APIとして公開しているものがなく、HTMLからの抽出は、処理の重さや信頼性、あとマナー的にもどうなのということで断念。はやくAPI作ってくださいな・・・。

WorldCatLCも視野に入れたけど、労力の割にそれほどメリットもないので、今回は無視。NDLがWorldCatに情報提供してれば使ったかもなのになあ。

で、amazonのAPI(Amazon Associates Web Service)は超有名なだけあって、簡単に使えた。

PHPのサンプル探してたら、こちらのページがわかりやすかった。

で、今度は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

検索
フィード
メタ情報

ページの上部に戻る