using System;
using System.Collections;
/*
此类的功能,是读取ISO2709数据
得到ISO2709数据三个段,头标\目次\数据
获得字段信息
获得子字段信息
*/
namespace Nosi.Library
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
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是由于目次区结束标识符
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<strMuci.Length);
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 ++;
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
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;
}
}
}
}