国会図書館サーチが提供するOAI-PMHは、解説ページに記載されているようなリクエストURLによってRDFフォーマットの書誌データを取得する仕組みだが、「OAI-PMH」というのが「Open Archives Initiative's Protocol for Metadata Harvesting」の略称である通り、メタデータのHarvesting(刈取り)用ツールを活用することで、より便利にメタデータをHarvestingすることができる。
先日 id:npn2sc1815j さんが国会図書館デジタルコレクションの(ほぼ)全メタデータを使用して、近代デジタルライブラリー登録資料におけるパブリックドメイン古書の点数を高い精度で推計されたのも、こうした刈取りツールの活用による。
備忘のため、OAIHarvester2という刈取りツールによる書誌データの取得法(主にツイッターで id:2sc1815j さんにお教えいただいたもの)をメモる。
例文:2013年7月1日〜2013年7月10日までにNDL Searchに登録・更新されたNDL-OPACの「作成完了書誌」のメタデータをdcndl形式で取得する。
java -classpath .;log4j-1.2.12.jar;harvester2.jar;xalan.jar ORG.oclc.oai.harvester2.app.RawWrite -from 2013-07-01 -until 2013-07-10 -metadataPrefix dcndl_simple -setSpec ndl-dl -out ndl_dl.xml http://iss.ndl.go.jp/api/oaipmh
上記は国会図書館サーチのOAI-PMHにリクエストURLのサンプルが記されていた例文を、(Windows版)OAIHarvester用のバッチファイルとして記したもの。dcndl-simple形式で取得したメタデータを「ndl_dl.xml」ファイルに書き出すようになっている。
より長期間のデータを取得する場合、少なくとも自分のケースでは、何度もDOS窓ごと落ちて作業が終了(中断)した。その場合、前回終了時に記録されたXMLファイルの末尾付近をチェックし、resumptionTokenの値を追記すれば、前回の続きから追加取得することができる。
java -classpath .;log4j-1.2.12.jar;harvester2.jar;xalan.jar ORG.oclc.oai.harvester2.app.RawWrite -from 2014-01-01 -until 2014-12-31 -metadataPrefix dcndl_simple -setSpec ndl-dl -out ndl_dl2014c.xml http://iss.ndl.go.jp/api/oaipmh -resumptionToken 2014-01-01/2014-12-31/ndl-dl/dcndl_simple///R100000039-I000330612-00
そうやって5日ほどかけて取得したXMLファイルは、次のような構造になっている。
ルート | 親要素 | 子要素 | 内容 |
---|---|---|---|
harvest | OAI-PMH | responseDate | 日付 |
request | リクエスト内容 | ||
Identify | リポジトリ名など | ||
OAI-PMH | responseDate | 日付 | |
request | リクエスト内容 | ||
ListMetaDataFormats | 使用メタデータ形式 | ||
OAI-PMH | responseDate | 日付 | |
request | リクエスト内容 | ||
ListSets | 使用リスト(国会図書館外含む) | ||
OAI-PMH | responseDate | 日付 | |
request | リクエスト内容 | ||
ListRecords | 書誌データ等 |
235万件という膨大な書誌データであるため、4番目のOAI-PMH要素が繰り返し出現する。そのListRecords要素は、次の内容になっている。
子要素 | 孫要素 | 曾孫要素 | 内容 |
---|---|---|---|
ListRecords | record | header | 書誌IDなど |
metadata | 書誌データ | ||
record | header | ||
metadata | |||
中略 | |||
record | header | ||
metadata | |||
resumptionToken | 継続用トークン |
国会図書館サーチにおけるAPIの仕様上、ひとつのListRecordsは200件のrecordと、末尾のresumptionTolenを持つ。
書誌データ本体であるmetadataは、次のようになっている(一部抜粋)。
曾孫要素 | 玄孫要素 | 来孫要素 | 内容 |
---|---|---|---|
metadata | dcndl_simple:dc | dc:identifier | URI |
dc:title | タイトル | ||
dc:creator | 著作者 | ||
dcterms:issued xsi:type="dcterms:W3CDTF" | 刊行年 | ||
dc:subject xsi:type="dcndl:NDC" | 日本十進分類 | ||
dcndl:materialType | 資料の種別(「図書」など) | ||
dcterms:rights | 著作権の状態 |
例えば、正岡子規『莫逆詩文 第一集』なら次のようになっている。
曾孫要素 | 玄孫要素 | 来孫要素 | 内容 |
---|---|---|---|
metadata | dcndl_simple:dc | dc:identifier | http://iss.ndl.go.jp/books/R100000039-I000695782-00 |
dc:title | 莫逆詩文 | ||
dc:creator | 正岡, 子規, 1867-1902 | ||
dcterms:issued xsi:type="dcterms:W3CDTF" | 1886 | ||
dc:subject xsi:type="dcndl:NDC" | 919.6 | ||
dcndl:materialType | 図書 | ||
dcterms:rights | インターネット公開(保護期間満了) |
したがって、OAIHarvester2によって刈り集めた国会図書館デジタルコレクションの書誌データをBaseXのようなXMLデータベースに収納し、XQueryで問合せを行う場合、次のようにすればよい。
- dcndl_simple:dc要素を検索対象とする
//*:dc
(コロンの後ろ側にdcを取るのはdcndl_simple:dc要素だけのようである)- その子要素が図書データを示すもの
/*:materialType[text() eq '図書']
- その子要素が1886年刊行を示すもの
/*:issued[starts-with(., '1886')]
- その子要素がNDC9類を示すもの
/*:subject[@xsi:type[contains(., 'NDC')] and starts-with(., '9')]
- その子要素がインターネット公開資料を示すもの
/*:rights[starts-with(., 'インターネット公開')]
これらをまとめて実行する際、BaseXならXQueryパネルに次のように入力する。
for $i in //*:dc where $i/*:materialType[text() eq '図書'] and $i/*:issued[starts-with(., '1886')] and $i/*:subject[@xsi:type[contains(., 'NDC')] and starts-with(., '9')] and $i/*:rights[starts-with(., 'インターネット公開')] return $i
すると、しばらくして1258件ほどの書誌データが抽出される。近代デジタルライブラリーで検索した結果 http://kindai.ndl.go.jp/search/searchResult?ndc=9&issuedTo=1886&issuedFm=1886&reshowFlg=1&detailSearchTypeNo=K&rows=20 と(現時点で)
同じ点数となっている。
以上、ツイッターで @2sc1815j さんに大変お世話になったもの。
@uakira2 祝・収穫祭! for $i in //*:dc where $i/*:materialType[text() eq '図書'] and $i/*:issued[starts-with(., '1886')] and
@uakira2 $i/*:subject[@ xsi:type[contains(., 'NDC')] and starts-with(., '913')] and $i/*:rights[starts-with(., 'インターネット公開')] return $i
後日様々なクエリを行う際に細部を忘れているだろうから、備忘のため記す。