MARC數據產生與發展
MARC數據最早產生於美國。1961年,美國國會圖書館開始圖書館自動化的構想,隨著計算機技術的進步,1963年,美國國會圖書館組織了在內部工作中採用電子計算機技術的可行性調查,1966年1月,產生了《標準機器能讀目錄款式的建議》,即MARC-1格式,1967年提出MARC-2,它是目前使用的各種機讀目錄格式的母本。1969年開始向全國發行MARCII格式書目磁帶,並將MARCII格式稱為US- MARC,即美國機器可讀目錄。作為一種計算機技術發展早期形成的數據格式,這一格式在定義時比較充分地照顧到圖書館書目數據在文獻形式描述、內容描述、檢索等方面的需要,表現為:欄位數量多;著錄詳盡;可檢索欄位多;定長與不定長欄位結合,靈活實用;保留主要款目及傳統編目的特點;擴充修改功能強;並能在實踐中不斷發展完善。美國機讀目錄適合美國國情,英法等國家根據各自情況創建了自己的機讀目錄,為了進一步協調、促進國際交流,統一各國機讀目錄格式,國際圖書館聯合會在USMARC基礎上制訂了“國際機讀目錄通信格式”,即UNIMARC,現在許多國家都採用UNIMARC進行文獻編目。CNMARC簡介
CNMARC是中國機讀目錄(China Machine-Readable Catalogue)的縮寫,是用於中國國家書目機構同其它國家書目機構以及中國國內圖書館與情報部門之間,以標準的計算機可讀形式交換書目信息。中國機讀目錄研製於20世紀70年代。1979年成立了全國信息與文獻標準化技術委員會,成立北京地區機讀目錄研製小組;1982年,中國標準總局公布了參照ISO2709制定的國家標準《文獻目錄信息交換用磁帶格式》(GB2901-82),為中文MARC格式的標準化奠定了基礎;1986年UNIMARC中譯本面世。在此基礎上,根據我國實際情況,編制《中國機讀目錄通訊格式》討論稿,1992年2月正式出版《中國機讀目錄通訊格式》,即CN-MARC。CNMARC格式為我國機讀目錄實現標準化、與國際接軌,從數據結構方面提供了保障。ISO2709的格式
cnMarc主要分為三個段,頭標 目次 數據三個區.頭標區
1. 定義該部分包含根據ISO 2709 制訂的對記錄進行處理時所需的通用信息。
2. 出現情況
記錄頭標區出現在每個記錄的開頭,它是必備的和不可重複的。
3. 欄位號、指示符和子欄位
記錄頭標沒有欄位號、指示符或子欄位標識。
4. 定長數據元素
頭標中的數據元素是由字元位置標識的。頭標的總長度為24個字元。字元位置規定從
0-23。
固定長數據元素表
數據元素名稱 字元數 字元位置
(1)記錄長度 5 0-4
(2)記錄狀態 1 5
(3)執行代碼 4 6-9
(4)指示符長度 1 10
(5)子欄位標識符長度 1 11
(6)數據起始地址 5 12-16
(7)記錄附加定義 3 17-19
(8)地址目次區結構 4 20-23
. 內容注釋
記錄頭標定位在每個記錄的開頭,它包含處理記錄的需的數據。
字元位9,10,11,20-23
所含的特定值可通過電腦程式生成。字元位0-4和12-16所含 的是數字型數據,它
表示記錄中相應部分的字元數量可能由計算機在生成記錄時產生。
字元位5,6-9,17-19
的值,如果採用外來源數據,可以從源記錄數據中通過轉換程式生成。若使用本格式製作源記錄,則
由、手工指定。
詳細內容見詳細窗固定長模板.
相關欄位
記錄頭標中提供的數據元素在格式的其它部分是沒有的。雖然執行代碼的一些值,
如“記錄類型”和“書目級別”與其它代碼數據有些相重,但事實上頭標里的代碼表示
的是記錄的特徵,而不是直接表示書目實體本身特徵。
目次區
目次區由一串數字構成,主要反映該記錄中的具有欄位在數據區的起始位置及長度.每12位表示一個欄位信息1-3:欄位名
4-7:長度
8-12:起始位置
數據區
根據目次區的折分信息可獲得欄位內容,再通過子欄位的分隔設定鋒得具體子段/子欄位內容記錄分隔設定的ASCII值為29
欄位分隔設定的ACSII 值為30
子欄位分隔設定的ASCII值為31
C#讀取ISO2709數據代碼
有時候我們需要在C#中讀取ISO02709數據,但是有很多新手對這個還不會,今天花了一點時間特意寫了這個代碼,希望對大家有幫助。using System;using System.Collections;
/*
此類的功能,是讀取ISO2709數據
得到ISO2709數據三個段,頭標\\目次\\數據
獲得欄位信息
獲得子欄位信息
*/
namespace Nosi.Library
{
///
/// Class1 的摘要說明。
///
public class Marc
{
#region 常量定義
public const char FLDEND = (char)30; // 欄位結束符
public const char RECEND = (char)29; // 記錄結束符
public const char SUBFLD = (char)31; // 子欄位指示符
public const int FLDNAME_LEN = 3; // 欄位名長度
public const int MAX_MARCREC_LEN = 100000; // MARC記錄的最大長度
#endregion
string m_strMarc = \"\"; // MARC記錄體
public Marc()
{
//
// TODO: 在此處添加構造函式邏輯
//
}
//獲得頭標
private string GetHeader()
{
string strHeader = null;
strHeader = m_strMarc.Substring(0,24);
return strHeader;
}
//獲得目次
private string GetMuci()
{
char[] charr = m_strMarc.ToCharArray();
string strMuci = null;
int i = 24; // 頭標字元不再讀取
while(i < m_strMarc.Length)
{
strMuci += charr[i].ToString();
if(charr[i] == FLDEND) break; //發現欄位標識
i++;
}
return strMuci;
}
// 獲得數據區
private string GetData()
{
string strData = null;
int iMuci = this.GetMuci().Length;
int iHeader = this.GetHeader().Length;
int iMarc = m_strMarc.Length;
strData = m_strMarc.Substring(iMuci + iHeader,iMarc - iMuci - iHeader);
return strData;
}
// 獲得目次區中的欄位名
// -1 error
// 0 no found
// 1 found
private int GetFieldPos(string strFieldName,
int nIndex,
out string strFieldPos)
{
string strMuci = this.GetMuci();
strFieldPos = null;
int i = 0;
int nRet = 0;
if(strMuci == null)
return -1;
if((strMuci.Length - 1) % 12 != 0) // 減1是由於目次區結束標識符[Page]
return -1; // length error
do
{
if(strMuci.Substring(i,3) == strFieldName)
nRet ++;
if(nRet == nIndex)// from zero add
{
strFieldPos = strMuci.Substring(i,12);
break;
}
i += 12;
} while(i
if (strFieldPos == null)
return 0; // no found
return 1;
}
// 通過 欄位名,欄位中出現次數獲得欄位內容
// 次數從 1 開始計數
// -1 error
// 0 no found
// 1 found
public int GetField(string strFldName,
int nIndex,
out string strFld)
{
strFld = null;
string strFldPos = null;
int nRet = this.GetFieldPos(strFldName,nIndex,out strFldPos);
if (nRet != 1)
return nRet;
if(strFldName.Length != 3 )
return -1; // subfield must 3 chars
int nLength = int.Parse( strFldPos.Substring(3,4));
int nBeginPos = int.Parse( strFldPos.Substring(7,5));
char[] chData = this.GetData(). ToCharArray();
int nPos =0;
int i = 0;
while( nPos < chData.Length)
{
i += GetCharLength(chData[nPos]);
if((i >= nBeginPos) && i<= (nBeginPos + nLength))
strFld += chData[nPos].ToString();
nPos ++;
}
if(strFld == null)
return 0;
return 1;
}
//從欄位中獲得出現次數的子欄位
// -1 error
// 0 not found
// 1 found
public int GetSubField(string strFld,
string strSubName,
int nIndex,
out string strSubFld)
{
strSubFld = null;
if(strSubName.Length != 1)
return -1; // subfield\'symbol char must 1 char
if(strFld == null)
return -1;
char[] chData = strFld.ToCharArray();
int nPos = 0;
bool isNewSub = false;
int nFound = 0; // 0: not 1: first time found 2: second time found
while( nPos < chData.Length)
{
nPos ++; [Page]
if((chData[nPos-1] == SUBFLD) && (chData[nPos].ToString() == strSubName))
nFound ++; // found if ((nFound == nIndex) && (isNewSub == false))
{
if(chData[nPos] == SUBFLD)
{
isNewSub = true;
break;
}
strSubFld += chData[nPos].ToString();
}
}
if(strSubFld == null)
return 0;
return 1;
}
//從欄位組中獲得子欄位
// -1 error
// 0 not found
// 1 found
public int GetSubField(string strGroup,
string strSubName,
out string strSubFld)
{
strSubFld = null;
if(strSubName.Length != 1)
return -1; // subfield\'symbol char must 1 char
if(strGroup == null)
return -1;
char[] chData = strGroup.ToCharArray();
int nPos = 0;
bool isNewSub = false;
int nFound = 0; // 0: not 1: first time found 2: second time found
while( nPos < chData.Length)
{
nPos ++;
if((chData[nPos-1] == SUBFLD) && (chData[nPos].ToString() == strSubName))
nFound ++; // found
if (isNewSub == false)
{
if(chData[nPos] == SUBFLD)
{
isNewSub = true;
break;
}
strSubFld += chData[nPos].ToString();
}
}
if(strSubFld == null)
return 0;
return 1;
}
//從欄位中獲得出現次數欄位組
// -1 error
// 0 not found
// 1 found
public int GetFieldGroup(string strFld,
int nIndex,
out string strGroup)
{
strGroup = null;
if(strFld == null)
return -1;
char[] chData = strFld.ToCharArray();
int nPos = 0;
string strSplit = \"a\"; // 一般以a子欄位為欄位組區分
int nFound = 0; // 0: not 1: first time found 2: second time found[Page]
while( nPos < chData.Length)
{
nPos ++;
if((chData[nPos-1] == SUBFLD) && (chData[nPos].ToString() == strSplit))
nFound ++; // found
if (nFound == nIndex)
strGroup += chData[nPos].ToString();
if(nFound > nIndex)
break;
}
if(strGroup == null)
return 0;
return 1;
}
//獲得字元的長度
//
private int GetCharLength(char ch)
{
int nLength = 0;
if((short)ch < 0 || (short)ch > 128)
{
nLength += 2;
}
else
{
nLength = nLength + 1;
}
return nLength;
}
public string strMarc
{
get
{
return m_strMarc;
}
set
{
m_strMarc = value;
}
}
}
}