티스토리 뷰

도서관리 패키지나 솔루션 기타 ASP 서비스를 검토하는 과정에서 제일 골치 아픈 일거리 중에 하나가 바로 책 정보를 일일이 등록하는 것이다.

아무리 도구가 잘 만들어져 있다 할지라도 자신이 보유하거나 조직에서 보유하고 있는 책들을 하나씩 시스템에 등록하기란 ......
개인적으로 자신이 가지고 있는 도서들의 책 제목, 지은이, 출판사 정도의 정보만 입력하는 일도 그야말로 "억" 소리나는 짜증나는 작업이다.
게다가 OpenBiblio에서 처럼 목록 정보외에도 사본(Copy) 정보까지 일일이 만들어 주어야 한다면 ...진짜 힘든일이라고 누구나 동의할 수 있을것 같다.
 
그런데, 이 작업을 바코드 스캐너 하나로 아주 간단하게 처리하는 방법이 있다.
도서관 간의 정보 교환에 사용하는 프로토콜로 Z39.50이 있는데 프로토콜이 복잡하기 때문에
최근에는 OPENAPI나 SRU(Search/Retrieval via URL) 등의 이름으로 사용자들이 손쉽게 정보를 검색할 수 있도록 서비스를 제공하는데,
바코드 스캐너로 도서의 ISBN을 읽어 공공 도서관 서비스를 통해 도서 정보를 검색하고 XML 형태로 전달된 검색 결과를 시스템에 자동 등록하는 방식이다.
 
우리나라의 경우에는 국립중앙도서관에서 OPENAPI형태로 서비스를 제공하고 있고, 미의회도서관의 경우에는 SRU(Search/Retrieval via URL) 라는 이름으로 서비스를 제공하는데 검색 결과는 MARC 내용을 XML 형태로 표시한 것이다.
 
아래 그림은 OpenBiblio>목록관리에 추가된 ISBN 기반 자동 도서 등록 기능의 모습이다.



자료 종류와 분류를 선택한 상태에서 ISBN 필드에 커서를 두고 바코드를 읽히면 ISBN 입력 여부(10자리 또는 13자리)를 검사하여 서버로 ISBN정보를 전송하고 서버에서 국립중앙도서관을 우선 검색하고, 없으면 미국의회도서관을 검색하여 목록정보와 사본정보를 자동 등록한다. ISBN을 읽히기 이전에 사본 바코드를 ISBN으로 사용할지 아니면 자동 발급 번호로 사용할지, 사본은 추가 하지 않을지를 선택할 수 있다. 사본 바코드번호를 별도로 발급하지 않고 ISBN을 그대로 활용하면 사본 바코드를 별도로 인쇄하지 않아도 되는 장점이 있으나, 동일 책이 여러개인 경우에는 사본 바코드를 별도 발급해야 하고, 책의 바코드가 없거나 잘못 인쇄된 경우 또한 별도 사본 바코드 발급이 필요하다. 그렇지만 개인 소장용 책을 관리하거나 중소규모 조직의 책을 관리할 때는 대부분 한권의 책 소장이 일반적이므로 isbn을 사본 바코드로 활용하는 방안도 고려할만하다고 생각된다. 다음 그림은 국립중앙도서관에서 책을 검색하여 자동 등록한 결과화면과 실제 등록 내용이다.



일단 책을 자동등록하는 시점에서는 여러권을 한꺼번에 작업하는 경우가 대부분이므로 연속작업에 무리가 없도록 직전에 선택했던 사항들을 유지시키고 키보드 포커스를 ISBN에 두고있다.
 
도서 검색에서도 사본 바코드 번호를 ISBN으로 했기 때문에 사본 바코드에 책의 ISBN을 읽히고 검색할 수 있다.

   
바코드 번호에 ISBN을 읽히고 검색한 결과는 아래의 그림과 같다.



국립중앙도서관과 미의회도서관 검색 결과를 자동 등록하는 과정에서 모든 정보는 KORMARC 기반으로 저장한다. 특히 국립중앙도서관 검색 결과에는 책 표지 이미지의 주소가 있는 경우가 있는데 이런 경우에는 위의 그림과 같이 표지를 볼수 있도록 자동 링크 된다.
 
 

* 자동 도서 등록 기능 추가를 위한 팁

  1. ISBN 코드 변환
    ISBN이 10자리 코드가 있고 13자리 코드가 있는데 이 두가지 코드를 적절하게 사용해야 한다.
    위의 예제에서는 브라우저에서 실제 스캔된 코드와 함께 10자리 코드와 13자리 코드를 모두 만들어서 서버로 전송한다.
    다음은 10자리를 13자리로 변환하는 Java script이다.
    var sum = 38 + 3 * (parseInt(isbn10[0]) + parseInt(isbn10[2]) + parseInt(isbn10[4]) + parseInt(isbn10[6])
     + parseInt(isbn10[8])) + parseInt(isbn10[1]) + parseInt(isbn10[3]) + parseInt(isbn10[5]) + parseInt(isbn10[7]);
    var checkDig = (10 - (sum % 10)) % 10;
    return "978" + isbn10.substring(0, 9) + checkDig;
    다음은 13자리를 10자리로 변환하는 Java script이다.
    var start = isbn13.substring(3, 12);
    var sum = 0;
    var mul = 10;
    var i;
    for(i = 0; i < 9; i++) {
        sum = sum + (mul * parseInt(start[i]));
        mul -= 1;
    }
    var checkDig = 11 - (sum % 11);
    if (checkDig == 10) {
        checkDig = "X";
    } else if (checkDig == 11) {
        checkDig = "0";
    }
    return start + checkDig;
    위의 예제에서는 국립중앙도서관에서 10자리로 검색하여 없으면 13자리로 검색하고 그래도 없으면 미의회도서관에서 10자로 검색하고 없으면 13자로 검색하는 방식으로 적용했다.
     
  2. 국립중앙도서관 OPENAPI
    국립중앙도서관의 OPENAPI에 대해서는 http://www.nl.go.kr/kolisnet/openApi/guide/index.php 를 참조한다.
      
    다음의 URL은 특정 ISBN을 검색하는 예제로 "value1="다음에 있는 값을 검색하려는 ISBN으로 대치시켜 검색하면 된다. 도서 자동 등록을 위해서는 이 방법을 서버 프로그램에서 적용해야하지만 웹브라우저에서도 간단히 테스트 해볼 수 있다.
      
    http://nl.go.kr/kolisnet/openApi/open.php?page=1&search_field1=ISBN&value1=8989345596&maxCount=1&per_page=1&collection_set=1  
     
    <?xml version="1.0" encoding="UTF-8" ?> <METADATA> <TOTAL>6</TOTAL> <RECORD> <NUMBER>1</NUMBER> <TITLE>TCP/IP 소켓 프로그래밍</TITLE> <AUTHOR>윤성우 저</AUTHOR> <PUBLISHER>프리렉</PUBLISHER> <PUBYEAR>2004</PUBYEAR> <TYPE>일반도서</TYPE> <CONTENTS>N</CONTENTS> <COVER_YN>N</COVER_YN> <LIB_NAME>용산도서관</LIB_NAME> <LIB_CODE>111019</LIB_CODE> <REC_KEY>28043948</REC_KEY> </RECORD> </METADATA>
    검색결과는 위와 같이 XML 형태로 보내지는데 국립중앙도서관의 경우에는 복잡한 레벨로 내려가지 않고 모든 정보가 RECORD 태그 내부에 동일 레벨로 나열된다. 특정 ISBN으로 검색되어진 목록의 상세 정보는 REC_KEY에 있는 제어번호를 가지고 아래의 주소로 다시 한번 검색하면 아래와 같이 표지 이미지 주소를(있을 경우만 전달됨) 포함하여 좀더 상세한 정보를 얻을 수 있다.

    http://nl.go.kr/kolisnet/openApi/open.php?rec_key=28043948
        
    <?xml version="1.0" encoding="UTF-8" ?> <METADATA> <BIBINFO> <TITLE_INFO>TCP/IP 소켓 프로그래밍 / 윤성우 저</TITLE_INFO> <PUBLISH_INFO>서울 : 프리렉, 2004</PUBLISH_INFO> <FORM_INFO>547p. : 삽도 ; 26cm</FORM_INFO> <SERIES_INFO>(熱血講義)</SERIES_INFO> <NOTE_INFO>INDEX : p. 541 - 547</NOTE_INFO> <STANDARD_INFO>ISBN: 89-89345-59-693000 : \25000</STANDARD_INFO> <CLASSFY_INFO>한국십진분류법 -&gt; 004.52</CLASSFY_INFO> <CONTENTS_YN>N</CONTENTS_YN> <ABSTRACTS_YN>N</ABSTRACTS_YN> <COVER_YN>N</COVER_YN> <UB_CONTROL_NO>UB20040122049</UB_CONTROL_NO> <ORIGINAL_YN>N</ORIGINAL_YN> <COPYRIGHT_YN>N</COPYRIGHT_YN> <LOCAL_CONTROL_NO>N</LOCAL_CONTROL_NO> <ISBN>8989345596</ISBN> <PRICE_INFO>\25000</PRICE_INFO> </BIBINFO> <HOLDINFO> <NUMBER>1</NUMBER> <LOCAL>11</LOCAL> <LIB_CODE>111019</LIB_CODE> <LIB_NAME>용산도서관</LIB_NAME> <CALL_NO>004.52-ㅇ627ㅌ</CALL_NO> </HOLDINFO> <HOLDINFO> <NUMBER>2</NUMBER> <LOCAL>11</LOCAL> <LIB_CODE>111020</LIB_CODE> <LIB_NAME>정독도서관</LIB_NAME> <CALL_NO>566.52-ㅇ627ㅌ</CALL_NO> </HOLDINFO> <HOLDINFO> <NUMBER>3</NUMBER> <LOCAL>11</LOCAL> <LIB_CODE>111031</LIB_CODE> <LIB_NAME>마포평생학습관아현분관</LIB_NAME> <CALL_NO>004.52-ㅇ627ㅌ</CALL_NO> </HOLDINFO> <HOLDINFO> <NUMBER>4</NUMBER> <LOCAL>11</LOCAL> <LIB_CODE>111038</LIB_CODE> <LIB_NAME>강북청소년문화정보센터</LIB_NAME> <CALL_NO>005.2-ㅇ627ㅌ</CALL_NO> </HOLDINFO> <HOLDINFO> <NUMBER>5</NUMBER> <LOCAL>21</LOCAL> <LIB_CODE>121024</LIB_CODE> <LIB_NAME>부산광역시 수영구도서관(통합도서)</LIB_NAME> <CALL_NO>005.2-윤54티</CALL_NO> </HOLDINFO> <HOLDINFO> <NUMBER>6</NUMBER> <LOCAL>42</LOCAL> <LIB_CODE>142005</LIB_CODE> <LIB_NAME>동해도서관</LIB_NAME> <CALL_NO>004.52-ㅇ627ㅌ</CALL_NO> </HOLDINFO> <HOLDINFO> <NUMBER>7</NUMBER> <LOCAL>42</LOCAL> <LIB_CODE>142027</LIB_CODE> <LIB_NAME>횡성도서관</LIB_NAME> <CALL_NO>004.52-ㅇ627ㅌ</CALL_NO> </HOLDINFO> <HOLDINFO> <NUMBER>8</NUMBER> <LOCAL>43</LOCAL> <LIB_CODE>143022</LIB_CODE> <LIB_NAME>청주시립정보도서관</LIB_NAME> <CALL_NO>004.52-윤53ㅌ</CALL_NO> </HOLDINFO> <HOLDINFO> <NUMBER>9</NUMBER> <LOCAL>44</LOCAL> <LIB_CODE>144009</LIB_CODE> <LIB_NAME>충청남도서부평생학습관</LIB_NAME> <CALL_NO>004.52-윤53ㅌ</CALL_NO> </HOLDINFO> <HOLDINFO> <NUMBER>10</NUMBER> <LOCAL>44</LOCAL> <LIB_CODE>144040</LIB_CODE> <LIB_NAME>충청남도교육청평생교육원</LIB_NAME> <CALL_NO>004.52-윤성우티</CALL_NO> </HOLDINFO> <HOLDINFO> <NUMBER>11</NUMBER> <LOCAL>48</LOCAL> <LIB_CODE>148035</LIB_CODE> <LIB_NAME>의창도서관</LIB_NAME> <CALL_NO>SO004.52-윤54티</CALL_NO> </HOLDINFO> </METADATA>
     
  3. 미국 의회 도서관 SRU 서비스
    영문으로 된 원서등을 검색 등록하기 위한 것으로 국립중앙도서관에서 ISBN이 검색 되지 않으면 바로 미국 의회 도서관을 검색하도록 했다. 국립중앙도서관의 OPENAPI처럼 URL로 직접 검색할 수 있고 결과가 XML형태라는 것은 유사하지만 아래의 내용과 같이 단순 레벨의 XML이 아니라 MARC기반으로 다중 레벨의 구성이라는 점에서 차이가 있다. 검색시 bath.isbn=다음에 ISBN을 입력하면 된다. URL 접근이므로 웹 브라우저에서 단순하게 테스트 해 볼 수도 있다.
     
    http://lx2.loc.gov:210/LCDB?operation=searchRetrieve&version=1.1&query=bath.isbn=1578700973&maximumRecords=4&recordSchema=marcxml
      
    <?xml version="1.0"?> <zs:searchRetrieveResponse xmlns:zs="http://www.loc.gov/zing/srw/"><zs:version>1.1</zs:version><zs:numberOfRecords>1</zs:numberOfRecords><zs:records><zs:record><zs:recordSchema>marcxml</zs:recordSchema><zs:recordPacking>xml</zs:recordPacking><zs:recordData><record xmlns="http://www.loc.gov/MARC21/slim"> <leader>01085cam a2200301 a 4500</leader> <controlfield tag="001">202042</controlfield> <controlfield tag="005">20000331145844.0</controlfield> <controlfield tag="008">990308s1999 inua 001 0 eng </controlfield> <datafield tag="035" ind1=" " ind2=" "> <subfield code="9">(DLC) 99061686</subfield> </datafield> <datafield tag="906" ind1=" " ind2=" "> <subfield code="a">7</subfield> <subfield code="b">cbc</subfield> <subfield code="c">orignew</subfield> <subfield code="d">2</subfield> <subfield code="e">opcn</subfield> <subfield code="f">19</subfield> <subfield code="g">y-gencatlg</subfield> </datafield> <datafield tag="925" ind1="0" ind2=" "> <subfield code="a">acquire</subfield> <subfield code="b">2 shelf copies</subfield> <subfield code="x">policy default</subfield> </datafield> <datafield tag="955" ind1=" " ind2=" "> <subfield code="a">pn09/e-pcn 03-08-99; to ASCD pb18 01-12-00; jf00 01-13-00; jf03 03-09-00; jf08 03-14-00 to SL; jf25 2 copies to Dewey 03-31-00; aa11 03-31-00</subfield> </datafield> <datafield tag="010" ind1=" " ind2=" "> <subfield code="a"> 99061686 </subfield> </datafield> <datafield tag="020" ind1=" " ind2=" "> <subfield code="a">1578700973</subfield> </datafield> <datafield tag="040" ind1=" " ind2=" "> <subfield code="a">DLC</subfield> <subfield code="c">DLC</subfield> <subfield code="d">DLC</subfield> </datafield> <datafield tag="050" ind1="0" ind2="0"> <subfield code="a">TK5105.585</subfield> <subfield code="b">.R48 1999</subfield> </datafield> <datafield tag="082" ind1="0" ind2="0"> <subfield code="a">004.6</subfield> <subfield code="2">21</subfield> </datafield> <datafield tag="100" ind1="1" ind2=" "> <subfield code="a">Retana, Alvaro,</subfield> <subfield code="c">CCIE.</subfield> </datafield> <datafield tag="245" ind1="1" ind2="0"> <subfield code="a">Advanced IP network design /</subfield> <subfield code="c">Alvaro Retana, Don Slice, Russ White.</subfield> </datafield> <datafield tag="246" ind1="3" ind2="0"> <subfield code="a">Advanced IP network design</subfield> </datafield> <datafield tag="260" ind1=" " ind2=" "> <subfield code="a">Indianapolis, IN :</subfield> <subfield code="b">Cisco Press,</subfield> <subfield code="c">c1999.</subfield> </datafield> <datafield tag="300" ind1=" " ind2=" "> <subfield code="a">xviii, 343 p. :</subfield> <subfield code="b">ill. ;</subfield> <subfield code="c">24 cm.</subfield> </datafield> <datafield tag="440" ind1=" " ind2="0"> <subfield code="a">CCIE professional development</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">TCP/IP (Computer network protocol)</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Computer networks.</subfield> </datafield> <datafield tag="650" ind1=" " ind2="0"> <subfield code="a">Routers (Computer networks)</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">Slice, Don.</subfield> </datafield> <datafield tag="700" ind1="1" ind2=" "> <subfield code="a">White, Russ.</subfield> </datafield> </record></zs:recordData><zs:recordPosition>1</zs:recordPosition></zs:record></zs:records></zs:searchRetrieveResponse>
     
  4. PHP에서의 XML 처리
    국립중앙도서관이나 미국의회도서관에서 받은 XML 형태의 검색 결과는 아래의 예와 같이 PHP에서 제공하는 file_get_contents 함수 등을 사용하여 일단 스트링으로 받아둔다.
      
    $page = file_get_contents("http://nl.go.kr/kolisnet/openApi/open.php?page=1&search_field1=ISBN&value1=".$isbn10."&maxCount=1&per_page=1&collection_set=1");
      
    문자열 형태로 저장된 XML 스트링은 파싱의 과정이 필요한데, 예제에서는 아래의 예제와 같이 xml_parser_create 함수로 파서를 생성하고 xml_parse_into_struct 함수로 XML 파싱 결과를 작업이 편하도록 PHP 배열로 전환시켰다.
      
    $xml_parser = xml_parser_create("UTF-8");
    xml_parse_into_struct($xml_parser, $bookpage, $vals, $index);
    xml_parser_free($xml_parser);
      
    배열로 저장된 정보는 $index 배열에 태그 종류별로 해당 태그에 속한 것등의 $val 배열 인덱스가 기록되어 있는 형태이다. 예를 들어 국립중앙도서관의 RECORD 태그 아래에 있는 것들을 모두 찾아보려면 $index[RECORD]에 있는 $val배열로의 인덱스를 하나씩 살펴보면 되는 것이다.
      
    아래는 제목과 지은이를 찾아 KOMARC 항목에 맞도록 값을 집어 넣는 코드 예제이다.
                $biblio->setTitle($vals[$idx+1][value]);
                $fld = new_bibfield('245', 'a', '', true, $vals[$idx+1][value]); 
                $biblio->addBiblioField('245a', $fld);
              } else if ($vals[$idx+1][tag]=="AUTHOR") {
                $fld = new_bibfield('100', 'a', '', true, $vals[$idx+1][value]);
                $biblio->addBiblioField('100a', $fld);
     
  5. 자동등록에 활용할 OpenBiblio 클래스
    OPENAPI 및 SRU 결과 분석을 통하여 얻어진 정보들은 OpenBiblio 목록 및 사본 정보에 저장해야 하는데, 시스템에 내장되어 있는 클래스를 활용하면 좀더 편리하게 작업을 진행 할 수 있다.
    목록 정보는 classes/Biblio.php, classes/BiblioQuery.php, classes/MaterialFieldQuery.php,classes/BiblioField.php 코드를 불러들여 사용하고,  사본의 경우에는 classes/BiblioCopy.php, classes/BiblioCopyQuery.php 코드를 불러들여 사용하면 된다.
     

  
(주)동운시스템 전화 041-358-3760

동운북스 소개 바로가기
[온라인 문의 및 견적요청]

  
 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/03   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
글 보관함