PHPでISBNコードからNDC番号を求める

(1/1)
私は乱読派だが、読んだ本の記録を残している。これをどう分類するか考えた末に、図書館と同じ分類法(NDC;日本十進分類法)を利用することに決めた。図書館で借りた本は背表紙にNDC番号が貼ってあるからいいのだが、買った本は調べないとわからない。
そこで、前回紹介した ISBNコードから NDC番号を求めることはできないか考え、つくったのが今回紹介するプログラムである。

(2024年1月27日)「国立国会図書館サーチ」リニューアル対応,pahooInputData導入

目次

サンプル・プログラムの実行例

PHPでISBNコードからNDC番号を求める

サンプル・プログラム

このプログラムは国立国会図書館の総合目録ネットワークシステムを呼び出している。
圧縮ファイルの内容
isbn2ndc.phpサンプル・プログラム本体。
isbn2ndc.cfg前回利用時間を保持するファイル。
NDC9.csvNDCの第3次区分表(第9版)ファイル
pahooInputData.phpデータ入力に関わる関数群。
使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。
isbn2ndc.php 更新履歴
バージョン 更新日 内容
3.0.0 2024/01/27 「国立国会図書館サーチ」リニューアル対応
2.4.0 2024/01/27 pahooInputData導入
2.3 2021/05/04 PHP8対応,リファラチェック追加
2.2 2019/05/02 総合目録ネットワークシステム https 対応
2.1 2016/06/05 ハイフン無視,Amazon商品リンク
pahooInputData.php 更新履歴
バージョン 更新日 内容
1.4.1 2023/09/30 コメントの訂正
1.4.0 2023/09/09 $_GET, $_POST参照をfilter_input()関数に置換
1.3.0 2023/07/11 roundFloat() 追加
1.2.0 2023/04/22 exitIfLessVersion() 追加
1.1.2 2023/02/05 validString() 修正

NDC番号

NDC(Nippon Decimal Classification)は日本十進分類法とも呼ばれ、図書館で書籍を分類するために使われている10進数3桁の数字である。

書籍の出版時にはISBNコードは付与されるが、NDC番号は付与されない。あくまで図書館側が分類して付与するコードである。また、ISBNコードとNDC番号の正しい対応表(データベース)というものも存在しない。
そこで今回は、国立国会図書館の国立国会図書館サーチAPIを呼び出し、ISBNコードからNDC番号を求めることにする。
(※)以前は 総合目録ネットワークシステムを利用していたのだが、2024年(令和6年)1月5日に「国立国会図書館オンライン」と「国立国会図書館サーチ」を統合・リニューアルしたことに伴いプログラムが動作しなくなったため、APIを利用する方式に変更した。

解説:初期値

  49: //タイムゾーン未設定のシステム向け
  50: date_default_timezone_set('Asia/Tokyo');
  51: 
  52: //検索するISBNコードの初期値
  53: define('DEF_ISBN', '9784798135472');
  54: 
  55: //利用間隔(秒;相手システムに負荷をかけないために間隔を開ける)
  56: define('INTERVAL', 10);
  57: 
  58: //NDCの第3次区分表(第9版)を格納した外部ファイル
  59: define('FNAME_NDC9', './NDC9.csv');
  60: 
  61: //表示幅(ピクセル)
  62: define('WIDTH', 600);

総合目録ネットワークシステムに負荷をかけないため、INTERVAL で定義した間隔より短い間隔でプログラムが実行されないようにしている。

解説:ISBNコードからNDC番号を取得

 219: /**
 220:  * 国立国会図書館サーチAPIを呼び出し,ISBNコードからNDC番号を取得する.
 221:  * @param   string $isbn   ISBNコード
 222:  * @param   string $errmsg エラーメッセージ格納用
 223:  * @return  NDC番号/FALSE=取得失敗
 224: */
 225: function isbn2ndc($isbn, &$errmsg) {
 226:     //名前空間
 227:     define('NS_XSI', 'http://www.w3.org/2001/XMLSchema-instance');
 228:     define('NS_DC', 'http://purl.org/dc/elements/1.1/');
 229: 
 230:     //国立国会図書館サーチAPIを呼び出す.
 231:     $errmsg = '';
 232:     $query = 'isbn=' . preg_replace('/\-/', '', $isbn);
 233:     $url = 'https://iss.ndl.go.jp/api/opensearch?' . $query;
 234: 
 235:     $xml = @simplexml_load_file($url);
 236:     if ($xml == FALSE) {
 237:         $errmsg = '国立国会図書館サーチAPIの接続に失敗しました';
 238:         return FALSE;
 239:     }
 240:     //レスポンス・チェック
 241:     $count = @count($xml->channel->item);
 242:     if ($count <0) {
 243:         $errmsg = '検索結果がありません';
 244:         return FALSE;
 245:     }
 246:     //NDC番号を取得する.
 247:     $ndc = FALSE;
 248:     $node = $xml->channel->item->children(NS_DC);
 249:     foreach ($node->subject as $id) {
 250:         if (preg_match('/NDC/iu', (string)$id->attributes(NS_XSI)) == 1) {
 251:             $ndc = (string)$id;
 252:             break;
 253:         }
 254:     }
 255:     if ($ndc == FALSE) {
 256:         $errmsg = 'NDC番号が未登録です';
 257:         return FALSE;
 258:     }
 259:     return $ndc;
 260: }

ISBN番号からNDC番号を取得する関数は、「PHPで国立国会図書館を検索」で紹介したプログラムを簡略化し、NDC番号取得に特化した。

解説:分類名の取得

 195: /**
 196:  * NDC番号から分類名を取り出す
 197:  * @param   string $ndc NDC番号
 198:  * @return  分類名/FALSE=取得失敗
 199: */
 200: function ndc2class($ndc) {
 201:     $n2 = substr($ndc, 0, 2. '0';     //NDCの上2桁+'0'
 202:     $n3 = substr($ndc, 0, 3);           //NDCの上3桁
 203:     if (preg_match('/^[0-9]{3}$/', $n3!1)   return FALSE;
 204: 
 205:     $res = FALSE;
 206:     if (($fp = fopen(FNAME_NDC9, 'r')) == FALSE)    return FALSE;
 207:     while (! feof($fp)) {
 208:         $arr = fgetcsv($fp, 1000, "\t");
 209:         if ($arr[0] == $n2) {
 210:             $res = $arr[1. ' - ';
 211:         } else if ($arr[0] == $n3) {
 212:             $res .$arr[1];
 213:             break;
 214:         }
 215:     }
 216:     return $res;
 217: }

NDC番号という数字だけでは分類名が分かりにくいので、NDCの第3次区分表(第9版)を外部ファイル "NDC9.csv" に持たせ、求めたNDCから引くようにした。

おまけの話

分類したかった書籍約900冊のうち、ISBNがあるのに総合目録ネットワークシステムの検索に引っかからなかった書籍が2冊あった。また、検索にはかかるが、NDC番号が登録されていないものが4冊あった。そもそもISBNコードがない自費出版のような書籍が1冊あった。

このプログラムは、入力されたISBNコードのチェック(アルゴリズムは「PHPでISBNコードをASINコードに変換する」で用いたものと同じ)や、NDCが検出できなかった時にエラーを返すようにしてある。

国立国会図書館には、少なくとも日本国内で出版された全ての書籍がデータベース化されていると信じていたのだが、100%完璧ではないのだということを知らされた。分類作業の苦労が偲ばれる。

質疑応答

【質問】
お疲れ様です。
「isbn2ndc」のサンプルプログラムを実行すると「Sory, system error occured !」とエラーが返されますが、解決手段はごさいますでしょうか?
お手数をお掛けしますが、どうぞよろしくお願いいたします。
【回答】
サーバのタイムゾーン設定によるエラーでした。
プログラムを修正しましたのでお試しください。


【質問】 ゆきむら様
こんばんは、初めまして。
素敵なプログラムをありがとうございます。
PHPプログラムを実行を押すと「Sory, system error occured !」とエラーが出ます。
お忙しい中大変恐縮ですが、お返事頂けますと幸いです。
よろしくお願いいたします。
【回答】
現在、プログラムは正常に動作しています。
冒頭で紹介したとおり、国立国会図書館の総合目録ネットワークシステムを利用しています。相手システムに負荷をかけないよう、一度検索すると、10秒間は検索できないようになっています。また、頻繁に検索を行うと「Sory, system error occured !」と表示する可能性があります。

参考サイト

(この項おわり)
header