劉娉婷
(國(guó)家圖書館,北京10081)
MARC(Machine-Readable Cataloging)是機(jī)器可讀目錄的簡(jiǎn)稱,指利用計(jì)算機(jī)識(shí)讀和處理的目錄。它是文獻(xiàn)編目?jī)?nèi)容經(jīng)過(guò)計(jì)算機(jī)處理,以代碼形式記載在一定載體上而形成的一種目錄。MARC數(shù)據(jù)是描述文獻(xiàn)著錄項(xiàng)目的國(guó)際標(biāo)準(zhǔn)格式,是實(shí)現(xiàn)計(jì)算機(jī)處理書目信息及資源共享的基礎(chǔ)[1]。MARC數(shù)據(jù)最早產(chǎn)生于美國(guó),作為一種計(jì)算機(jī)技術(shù)發(fā)展早期形成的數(shù)據(jù)格式,這一格式在定義時(shí)比較充分地照顧到圖書館書目數(shù)據(jù)在文獻(xiàn)形式描述、內(nèi)容描述、檢索等方面的需要,具有字段數(shù)量多、著錄詳盡、可檢索字段多、定長(zhǎng)與不定長(zhǎng)字段結(jié)合、保留主要款目及傳統(tǒng)編目的特點(diǎn)、擴(kuò)充修改功能強(qiáng)等特點(diǎn)[2]。在文獻(xiàn)數(shù)字化建設(shè)的過(guò)程中,MARC數(shù)據(jù)是數(shù)字化項(xiàng)目中的一項(xiàng)重要元數(shù)據(jù),但MARC數(shù)據(jù)中的字段信息無(wú)法被直接使用,需要提取字段以及子字段信息,保存在可讀取的數(shù)據(jù)庫(kù)中。在對(duì)MARC數(shù)據(jù)的數(shù)據(jù)格式進(jìn)行深入分析后,筆者開發(fā)出可以自由選擇字段的MARC數(shù)據(jù)提取工具,該工具對(duì)MARC數(shù)據(jù)提取的字段信息沒有限制,可以進(jìn)行批量提取,筆者詳細(xì)介紹了該工具的實(shí)現(xiàn)原理和開發(fā)實(shí)踐,希望能為大家提供一定的借鑒。
提取MARC數(shù)據(jù)的前提是理解MARC數(shù)據(jù)的格式結(jié)構(gòu),下面詳細(xì)地說(shuō)明一下MARC數(shù)據(jù)的格式。
MARC數(shù)據(jù)格式是GB/T 2901(ISO 2709)的一個(gè)特定形式,規(guī)定了每一個(gè)用于交換的書目記錄必須遵循的標(biāo)準(zhǔn)記錄結(jié)構(gòu)。MARC數(shù)據(jù)由4部分組成:記錄頭標(biāo)、地址目次區(qū)、數(shù)據(jù)字段區(qū)和記錄結(jié)束符。MARC數(shù)據(jù)的記錄結(jié)構(gòu)如下圖1所示:
圖1 MARC數(shù)據(jù)的記錄結(jié)構(gòu)
根據(jù)GB/T 2901(ISO 2709)規(guī)定,記錄頭標(biāo)位于MARC數(shù)據(jù)的開頭,由24位字符組成,包含了處理MARC數(shù)據(jù)所需的數(shù)據(jù)元素,是必備的并且不能重復(fù)。記錄頭標(biāo)中的數(shù)據(jù)元素是由字符位置標(biāo)識(shí)的,字符位置起始于0,記錄頭標(biāo)的字符位置為0到23,數(shù)據(jù)元素具體如表1所示。
表1 記錄頭標(biāo)數(shù)據(jù)元素
地址目次區(qū)位于記錄頭標(biāo)之后,含有一個(gè)或多個(gè)目次項(xiàng),每個(gè)目次項(xiàng)描述一個(gè)字段,一個(gè)目次項(xiàng)包含3部分:字段標(biāo)識(shí)符、字段長(zhǎng)度和字段起始字符位置,其中字段標(biāo)識(shí)符由3位數(shù)字表示,字段長(zhǎng)度由4位數(shù)字表示,字段起始字符位置由5位數(shù)字表示,即一個(gè)目次項(xiàng)有12位,不允許出現(xiàn)其他字符。在地址目次區(qū)之后有一個(gè)字段分隔符。地址目次區(qū)的結(jié)構(gòu)如圖2所示。
圖2 地址目次區(qū)的結(jié)構(gòu)
每個(gè)目次項(xiàng)中的字段長(zhǎng)度是該字段全部字符數(shù)的總和,包括指示符、子字段標(biāo)識(shí)符、行文或代碼數(shù)據(jù)以及字段分隔符;字段起始字符位置是該字段第一個(gè)字符在數(shù)據(jù)字段區(qū)中的位置,第一個(gè)數(shù)據(jù)字段的第一個(gè)字符的位置為0。MARC數(shù)據(jù)中的數(shù)據(jù)字段的位置完全由地址目次區(qū)決定,每個(gè)數(shù)據(jù)字段都對(duì)應(yīng)地址目次區(qū)中的一個(gè)目次項(xiàng)。
數(shù)據(jù)字段區(qū)位于地址目次區(qū)之后,由若干定長(zhǎng)和變長(zhǎng)字段組成,每個(gè)字段之間用字段分隔符隔開。定長(zhǎng)字段的結(jié)構(gòu)圖3所示。
圖3 定長(zhǎng)字段結(jié)構(gòu)
變長(zhǎng)字段的結(jié)構(gòu)如圖4所示:
圖4 變長(zhǎng)字段結(jié)構(gòu)
001和005字段僅由數(shù)據(jù)和字段分隔符組成,其他字段由兩個(gè)字段指示符、一個(gè)或多個(gè)子字段以及字段分隔符組成,每個(gè)子字段的開頭是子字段標(biāo)識(shí)符,由1位子字段分隔符和1位子字段代碼組成,子字段代碼一般為英文字母或數(shù)字,子字段標(biāo)識(shí)符之后是代碼數(shù)據(jù)或正文數(shù)據(jù)。MARC數(shù)據(jù)中的字段和子字段原則上是可以重復(fù)的。這里要注意的是,字段標(biāo)識(shí)符保存在地址目次區(qū),在數(shù)據(jù)字段區(qū)是不存在的。
MARC數(shù)據(jù)中存在著一些特殊字符,用于分隔和控制MARC數(shù)據(jù)的格式,以便機(jī)器正確的識(shí)讀和處理MARC數(shù)據(jù),MARC數(shù)據(jù)中的特殊字符主要有下面幾種:
(1)字符集中的IS1,即子字段分隔符,用作子字段標(biāo)識(shí)符的第一位字符,標(biāo)志著子字段的開始,在雙八位編碼表中用001F表示,在格式文本中用$表示。
(2)字符集中的IS2,用作地址目次區(qū)的結(jié)尾和數(shù)據(jù)字段的分隔符,以隔開相鄰的數(shù)據(jù)字段,在雙八位編碼表中用001E表示,在格式文本中用*表示。
(3)字符集中的IS3,即記錄結(jié)束符,置于每條記錄的結(jié)尾以表示該記錄結(jié)束,在雙八位編碼表中用001D表示,在格式文本中用%表示。
圖5是一條MARC數(shù)據(jù),這里將不能顯示的特殊字符用可顯示的字符替代,其中IS1用$表示,IS2用*表示,IS3用%表示。
MARC數(shù)據(jù)作為一項(xiàng)重要的元數(shù)據(jù),在文獻(xiàn)數(shù)字化建設(shè)的過(guò)程中是必不可少的。從MARC數(shù)據(jù)的格式來(lái)看,字段和子字段的信息并不能夠直接使用,當(dāng)數(shù)據(jù)量比較大時(shí),手工錄入并不現(xiàn)實(shí),需要進(jìn)行提取保存到可讀取的數(shù)據(jù)庫(kù)中。不同載體類型的數(shù)字化項(xiàng)目需要提取的MARC數(shù)據(jù)的字段信息是有差異的,同時(shí)要考慮到字段或子字段重復(fù)的情況,筆者沒有發(fā)現(xiàn)合適的工具來(lái)滿足MARC數(shù)據(jù)的提取需求,一般是自己開發(fā)提取工具,筆者針對(duì)中文圖書、民國(guó)報(bào)紙、民國(guó)期刊、音視頻等不同的載體類型開發(fā)了多個(gè)工具。這些工具只能提取固定字段的信息,靈活性差,當(dāng)提取字段有變更時(shí)需要更新工具,不具備通用性,于是筆者萌生了開發(fā)一款可以自由選擇字段的MARC數(shù)據(jù)提取工具的想法,并最終完成了該工具的程序?qū)崿F(xiàn)。
以圖5中的MARC數(shù)據(jù)為例,詳細(xì)地介紹MARC數(shù)據(jù)提取原理,具體提取流程如下:
(1)讀取MARC數(shù)據(jù),每次讀取一行,假設(shè)現(xiàn)在讀取到的是圖5中的MARC數(shù)據(jù)。
圖5 MARC數(shù)據(jù)
(2)計(jì)算地址目次區(qū)中目次項(xiàng)的數(shù)量。該MARC數(shù)據(jù)的起始24個(gè)字符為記錄頭標(biāo),即“00911nam0 2200265 450”,記錄頭標(biāo)的第12-16位為數(shù)據(jù)基地址,也就是數(shù)據(jù)字段區(qū)的起始位置,這里是“00265”,即在該條MARC數(shù)據(jù)中數(shù)據(jù)字段區(qū)起始于第265個(gè)字符。數(shù)據(jù)基地址減去記錄頭標(biāo)的24個(gè)字符和地址目次區(qū)結(jié)尾的1個(gè)字段分隔符,就得到了地址目次區(qū)的總長(zhǎng)度,這里是240。每個(gè)目次項(xiàng)的長(zhǎng)度為12,用地址目次區(qū)的總長(zhǎng)度除以12就得到了地址目次區(qū)中目次項(xiàng)的數(shù)量,這里是20。
(3)獲取地址目次區(qū)中所有目次項(xiàng)的字段標(biāo)識(shí)符,按照順序存儲(chǔ)在數(shù)組中。每個(gè)目次項(xiàng)的前三位數(shù)字為字段標(biāo)識(shí)符。圖1中的MARC數(shù)據(jù)的地址目次區(qū)如圖6所示,每一行是一個(gè)目次項(xiàng),有標(biāo)記的前三位數(shù)字為字段標(biāo)識(shí)符。
圖6 地址目次區(qū)
(4)獲取數(shù)據(jù)字段區(qū)的每一個(gè)數(shù)據(jù)字段,按照順序存儲(chǔ)在數(shù)組中。這里要用到字段分隔符IS2,使用字段分隔符IS2將MARC數(shù)據(jù)進(jìn)行分割,去掉記錄開頭的記錄頭標(biāo)加地址目次區(qū)和記錄最后的記錄結(jié)束符,將得到全部的數(shù)據(jù)字段內(nèi)容。圖5中的MARC數(shù)據(jù)的數(shù)據(jù)字段區(qū)如圖7所示,每一行是一個(gè)數(shù)據(jù)字段。目次區(qū)中目次項(xiàng)的順序和數(shù)據(jù)字段區(qū)中字段內(nèi)容的順序是一致的,所以字段標(biāo)識(shí)符數(shù)組和數(shù)據(jù)字段數(shù)組中的內(nèi)容是一一對(duì)應(yīng)的,至此就獲得了MARC數(shù)據(jù)中全部的字段信息。
圖7 數(shù)據(jù)字段區(qū)
(5)按照需求提取字段內(nèi)容。將需要提取的字段標(biāo)識(shí)符和子字段標(biāo)識(shí)符存儲(chǔ)在一個(gè)數(shù)組中,依次在第(3)、(4)兩步獲取的數(shù)組中進(jìn)行查找,即可得到對(duì)應(yīng)的字段內(nèi)容。提取字段內(nèi)容時(shí)需要用到子字段分隔符IS1,利用IS1將數(shù)據(jù)字段進(jìn)行分解,通過(guò)子字段標(biāo)識(shí)符定位到對(duì)應(yīng)的子字段內(nèi)容。這里要注意001和005字段是沒有子字段分隔符的。在圖6中,第一行是001字段,第二行是005字段,第三行是010字段,取001和005字段的內(nèi)容,直接讀取圖3中的第一行和第二行的內(nèi)容,取010$a字段,需要將圖7中第三行的內(nèi)容進(jìn)行分解,以獲取到“978-7-5013-5978-3”。
(6)將字段內(nèi)容存儲(chǔ)在Microsoft Office Excel文件中,每一個(gè)子字段的內(nèi)容存儲(chǔ)為一列。選擇Microsoft Office Excel進(jìn)行存儲(chǔ)是因?yàn)槠渚哂徐`活性,列數(shù)可以動(dòng)態(tài)調(diào)整,符合自由選擇字段的需求,也可以方便的轉(zhuǎn)換為Microsoft Office Access等其他數(shù)據(jù)格式。
程序開發(fā)的硬件環(huán)境為普通PC機(jī),操作系統(tǒng)是Windows 7,開發(fā)平臺(tái)是Microsoft Visual Studio 2010,目標(biāo)框架使用的是.NET Framework 2.0,使用的編程語(yǔ)言是C#,PC機(jī)上必須安裝Microsoft Office Excel 2007和Microsoft Office Word 2007或更高版本。
自由選擇字段的MARC數(shù)據(jù)提取工具的界面如圖8所示。該工具有兩個(gè)主要功能:MARC數(shù)據(jù)提取和說(shuō)明文檔展示,這里主要介紹MARC數(shù)據(jù)提取的功能。
圖8 程序界面
MARC數(shù)據(jù)提取中主要包括字段間隔字符選擇、字段選擇、MARC數(shù)據(jù)查看和MARC數(shù)據(jù)提取4個(gè)功能,下面詳細(xì)地介紹一下這些功能:
(1)字段間隔字符選擇,間隔字符分為重復(fù)字段間隔字符和重復(fù)子字段間隔字符。在MARC數(shù)據(jù)中存在著字段重復(fù)和子字段重復(fù)的現(xiàn)象,該工具會(huì)將重復(fù)的字段和子字段全部提取,存儲(chǔ)在一個(gè)Excel單元格中,這就需要設(shè)置間隔字符將各個(gè)字段和子字段間隔開來(lái),以免造成閱讀困難。筆者將重復(fù)字段的間隔字符默認(rèn)設(shè)置為“;”,重復(fù)子字段的間隔字符默認(rèn)設(shè)置為“,”,用戶也可以根據(jù)需求設(shè)置間隔字符,如果沒有設(shè)置間隔字符則使用默認(rèn)的設(shè)置。
(2)字段選擇,包括添加字段、刪除字段、清空字段列表、導(dǎo)入字段和導(dǎo)出字段的功能。
點(diǎn)擊“添加”按鈕,彈出添加字段對(duì)話框,按提取需求填寫字段名稱和子字段名稱,如圖9所示。這里需要注意三點(diǎn):①子字段代碼只需要填寫英文字母或數(shù)字,不需要填寫子字段分隔符;②子字段代碼的英文字母大小寫需要與MARC數(shù)據(jù)保持一致;③001和005字段不需要填寫子字段代碼。字段標(biāo)識(shí)符和子字段代碼填寫完成后,點(diǎn)擊“確定”按鈕,字段將顯示在“已選字段”列表中,如圖10所示,用戶需要依次將提取的字段添加。
圖9 添加字段
圖10 已選字段
單擊“已選字段”列表中的某一行,點(diǎn)擊“刪除”按鈕,可以將該字段刪除,也可以雙擊該行進(jìn)行刪除操作。點(diǎn)擊“清空列表”按鈕,“已選字段”中的內(nèi)容將全部清除。
用戶添加完提取字段之后,為方便以后使用可以將字段列表導(dǎo)出。點(diǎn)擊“導(dǎo)出”按鈕,可以將“已選字段”列表中的內(nèi)容導(dǎo)出為后綴為“.list”的文本文件。在下一次使用時(shí),點(diǎn)擊“導(dǎo)入”按鈕,可以將該文本文件導(dǎo)入,不需要再一一添加字段內(nèi)容。
(3)MARC數(shù)據(jù)查看。首先選擇MARC數(shù)據(jù)文件的編碼方式,根據(jù)文件的實(shí)際編碼方式選擇,否則可能會(huì)顯示亂碼;然后選擇要查看的MARC數(shù)據(jù)文件,點(diǎn)擊“查看”按鈕,顯示結(jié)果如圖11所示,這里將子字段分隔符用藍(lán)色方框代替,以方便查看。用戶可以點(diǎn)擊“上一條”“下一條”按鈕來(lái)查看上一條和下一條MARC數(shù)據(jù),也可以輸入指定的數(shù)字,點(diǎn)擊“跳轉(zhuǎn)”按鈕跳轉(zhuǎn)到指定的MARC數(shù)據(jù)。
圖11 MARC數(shù)據(jù)查看
(4)MARC數(shù)據(jù)提取。在選擇MARC數(shù)據(jù)文件編碼方式和MARC數(shù)據(jù)文件之后,選擇要保存的Excel文件,點(diǎn)擊“提取”按鈕,會(huì)根據(jù)已選字段將MARC數(shù)據(jù)中的相應(yīng)字段內(nèi)容提取到Excel文件中。以提取001、200$a、200$f、210$a、210$c、210$d這5個(gè)字段為例,提取結(jié)果如圖12所示。該工具界面簡(jiǎn)潔、易于操作,能夠滿足工作中對(duì)MARC數(shù)據(jù)提取的各種需求,已經(jīng)被多人使用了多年,為工作提供了便利。
圖12 MARC數(shù)據(jù)提取結(jié)果
程序開發(fā)的關(guān)鍵點(diǎn)在于Excel文件的操作和MARC數(shù)據(jù)字段內(nèi)容的提取。
(1)Excel文件操作
Excel文件操作包括Excel文件的創(chuàng)建、寫入和保存,筆者使用Office的Excel組件來(lái)操作Excel文件,先引入Excel組件,在COM組件庫(kù)中找到Microsoft.Office.Interop.Excel,將其添加到引用中。Excel文件操作的關(guān)鍵代碼如下所示:
//定義一個(gè)COM中空類型的對(duì)象
object missing=System.Reflection.Missing.Value;
//創(chuàng)建Excel對(duì)象
Microsoft.Office.Interop.Excel.Application app=new Microsoft.Office.Interop.Excel.Application-Class();
app.Application.Workbooks.Add(true);
//添加新工作簿
Microsoft.Office.Interop.Excel.Workbook book=(Microsoft.Office.Interop.Excel.Workbook)app.Active-Workbook;
Microsoft.Office.Interop.Excel.Worksheet sheet=(Microsoft.Office.Interop.Excel.Worksheet)book.ActiveSheet;
//設(shè)置單元格格式為文本格式
Microsoft.Office.Interop.Excel.Range myrange=sheet.get_Range(sheet.Cells[1,1],sheet.Cells[cols_line.Count+1,al_field.Count+1]);
myrange.NumberFormatLocal="@";/
/給單元格賦值
sheet.Cells[1,1]="序號(hào)";
//保存Excel文件
book.SaveCopyAs(file_xls);
//關(guān)閉工作簿
book.Close(false,missing,missing);
//退出Excel
app.Quit();
(2)MARC數(shù)據(jù)字段內(nèi)容提取
首先根據(jù)記錄頭標(biāo)計(jì)算出MARC數(shù)據(jù)中字段的個(gè)數(shù),然后按照在MARC數(shù)據(jù)地址目次區(qū)中出現(xiàn)的順序,將所有的字段標(biāo)識(shí)符和數(shù)據(jù)字段內(nèi)容分別存儲(chǔ),最后與提取字段進(jìn)行匹配來(lái)提取字段內(nèi)容。MARC數(shù)據(jù)字段內(nèi)容提取的關(guān)鍵代碼如下所示:
//根據(jù)記錄頭標(biāo)計(jì)算出MARC數(shù)據(jù)中字段的個(gè)數(shù)
data_pos=int.Parse(line.Substring(12,5));
address_len=data_pos-24-1;
address_num=address_len/12;
//將字段標(biāo)識(shí)符存儲(chǔ)在al_label中
//使用字段分隔符將MARC數(shù)據(jù)分隔,數(shù)據(jù)字段內(nèi)容存儲(chǔ)在al_content中
//要提取的字段標(biāo)識(shí)符存儲(chǔ)在al_field中
//根據(jù)al_field中的字段標(biāo)識(shí)符依次尋找對(duì)應(yīng)的字段內(nèi)容
//001、005字段和其他字段內(nèi)容需要分別處理
//如果MARC數(shù)據(jù)中有相應(yīng)字段,提取字段內(nèi)容填入單元格中,如果沒有單元格為空
MARC數(shù)據(jù)在圖書館中應(yīng)用廣泛,是圖書館描述數(shù)據(jù)、存儲(chǔ)數(shù)據(jù)、處理數(shù)據(jù)的基礎(chǔ)。隨著圖書館事業(yè)的不斷發(fā)展,MARC數(shù)據(jù)始終作為元數(shù)據(jù)的標(biāo)準(zhǔn)之一,具有非常重要的作用。筆者開發(fā)的MARC數(shù)據(jù)提取工具為MARC數(shù)據(jù)的查看和提取提供了便利,在工作中的多次實(shí)踐證明了推廣該工具的可行性。目前該工具的功能還比較簡(jiǎn)單,未來(lái)筆者將增加字段的修改、增加、刪除功能,將該工具的功能做進(jìn)一步的完善,以便為工作提供更多的便利。