/// <summary> /// 将 USMARC 记录从 880 模式转换为 平行模式 /// </summary> /// <param name="record">要处理的记录</param> public static void ToParallel(MarcRecord record) { // 选定全部 880 字段 MarcNodeList fields = record.select("field[@name='880']"); if (fields.count == 0) { return; } foreach (MarcField field in fields) { string content_6 = field.select("subfield[@name='6']").FirstContent; if (string.IsNullOrEmpty(content_6) == true) { continue; } // 拆解 $6 内容 string strFieldName = ""; string strNumber = ""; string strScriptId = ""; string strOrientation = ""; _parseSubfield6(content_6, out strFieldName, out strNumber, out strScriptId, out strOrientation); if (string.IsNullOrEmpty(strScriptId) == true) { // 修正 $6 // 例子 ISBN 9789860139976 strScriptId = "$1"; field.select("subfield[@name='6']").Content = _buildSubfield6(strFieldName, strNumber, strScriptId, strOrientation); } // 找到关联的字段 MarcField main_field = _findField(record, strFieldName, field.Name, strNumber); if (main_field != null) { // 创建一个新的字段,把 880 字段内容复制过去 MarcField new_field = new MarcField(strFieldName, field.Indicator, field.Content); // 新字段插入到关联字段后面 main_field.after(new_field); // 删除 880 字段 field.detach(); main_field.select("subfield[@name='6']").Content = _buildSubfield6(strFieldName, strNumber, "", ""); } else { // 找不到关联的字段,把 880 字段的字段名修改了即可 field.Name = strFieldName; } } }
/// <summary> /// 创建平行字段 /// </summary> /// <param name="field">要创建平行字段的,包含汉字字符串的源字段</param> /// <param name="bTo880">将 field 字段名转为 880</param> /// <param name="getPinyin">获得拼音的函数地址</param> /// <param name="strError">返回出错信息</param> /// <returns>-1: 出错; 0: 成功; 1: field 不是中文的字段($6表示),无法创建平行字段</returns> public static int CreateParallelField(MarcField field, bool bTo880, Delegate_getPinyin getPinyin, out string strError) { strError = ""; if (field.ChildNodes.count == 0) { return(1); } MarcRecord record = (MarcRecord)field.Parent; MarcField main_field = null; string strFieldName = ""; string strNumber = ""; string strScriptId = ""; string strOrientation = ""; // 观察平行字段是否已经存在? string content_6 = field.select("subfield[@name='6']").FirstContent; if (string.IsNullOrEmpty(content_6) == false) { // 拆解 $6 内容 _parseSubfield6(content_6, out strFieldName, out strNumber, out strScriptId, out strOrientation); if (string.IsNullOrEmpty(strScriptId) == true) { strError = "field 的 $6 表明不是中文的字段,无法创建平行字段"; return(1); } // 找到关联的字段 main_field = _findField(record, strFieldName, field.Name, strNumber); } bool bNewField = false; if (main_field == null) { string strMainFieldName = field.Name; if (field.Name == "880") { // 只能靠 $6 中 linking tag if (string.IsNullOrEmpty(strFieldName) == true) { strError = "当前字段为 880 字段,但没有 $6 子字段,无法获得对应的字段名,因此函数调用失败"; return(-1); } strMainFieldName = strFieldName; } main_field = new MarcField(strMainFieldName, field.Indicator, ""); if (field.Name != "880") { field.before(main_field); } else { record.ChildNodes.insertSequence(main_field, InsertSequenceStyle.PreferTail); } bNewField = true; } else { // 内容全部删除。只是占用原有位置 main_field.Content = ""; main_field.Indicator = field.Indicator; } if (string.IsNullOrEmpty(strNumber) == true) { strNumber = _getNewNumber(record); } { // $6 MarcSubfield subfield_6 = new MarcSubfield("6", _buildSubfield6(bTo880 == true ? "880" : field.Name, strNumber, "", strOrientation) ); main_field.ChildNodes.add(subfield_6); } int nHanziCount = 0; List <MarcSubfield> remove_subfields = new List <MarcSubfield>(); // 其余子字段逐个加入 foreach (MarcSubfield subfield in field.ChildNodes) { if (subfield.Name == "6") { continue; } // 2014/10/20 if (subfield.Name == "9" || char.IsUpper(subfield.Name[0]) == true) { remove_subfields.Add(subfield); continue; } string strPinyin = getPinyin(subfield.Content, out strError); if (strPinyin == null) { strError = "创建拼音的过程出错: " + strError; return(-1); } if (strPinyin != subfield.Content) { nHanziCount++; } main_field.ChildNodes.add(new MarcSubfield(subfield.Name, strPinyin)); } // 2014/10/20 if (remove_subfields.Count > 0) { foreach (MarcSubfield subfield in remove_subfields) { subfield.detach(); } } if (nHanziCount == 0 && bNewField == true) { main_field.detach(); return(1); } // 当前字段加入 $6 { if (string.IsNullOrEmpty(strScriptId) == true) { strScriptId = "$1"; } MarcSubfield subfield_6 = null; MarcNodeList temp = field.select("subfield[@name='6']"); if (temp.count > 0) { subfield_6 = temp[0] as MarcSubfield; subfield_6.Content = _buildSubfield6(main_field.Name, strNumber, strScriptId, strOrientation); } else { subfield_6 = new MarcSubfield("6", _buildSubfield6(main_field.Name, strNumber, strScriptId, strOrientation) ); field.ChildNodes.insert(0, subfield_6); } } if (bTo880) { field.Name = "880"; } return(0); }
/// <summary> /// 将 USMARC 记录从 平行模式转换为 880 模式 /// </summary> /// <param name="record">要处理的记录</param> public static void To880(MarcRecord record) { List <MarcField> field_880s = new List <MarcField>(); foreach (MarcField field in record.ChildNodes) { if (field.Name == "880") { continue; } string content_6 = field.select("subfield[@name='6']").FirstContent; if (string.IsNullOrEmpty(content_6) == true) { continue; } // 拆解 $6 内容 string strFieldName = ""; string strNumber = ""; string strScriptId = ""; string strOrientation = ""; _parseSubfield6(content_6, out strFieldName, out strNumber, out strScriptId, out strOrientation); if (string.IsNullOrEmpty(strScriptId) == true) { continue; } // 至此 field 就是并列字段 // 找到关联的主字段 MarcField main_field = _findField(record, strFieldName, field.Name, strNumber); if (main_field != null) { // 修改并列字段的字段名为 880 field.Name = "880"; field.select("subfield[@name='6']").Content = _buildSubfield6(main_field.Name, strNumber, strScriptId, strOrientation); // 修改主字段的 $6 main_field.select("subfield[@name='6']").Content = _buildSubfield6("880", strNumber, "", ""); // 将 880 字段移动到顺次位置 } else { // 找不到关联的字段,把并列字段的字段名修改为 880 即可 field.Name = "880"; } field_880s.Add(field); } foreach (MarcField field in field_880s) { field.detach(); } foreach (MarcField field in field_880s) { record.ChildNodes.insertSequence(field, InsertSequenceStyle.PreferTail); } }
/// <summary> /// 创建平行字段 /// </summary> /// <param name="field">要创建平行字段的,包含汉字字符串的源字段</param> /// <param name="bTo880">将 field 字段名转为 880</param> /// <param name="getPinyin">获得拼音的函数地址</param> /// <param name="strError">返回出错信息</param> /// <returns>-1: 出错; 0: 成功; 1: field 不是中文的字段($6表示),无法创建平行字段</returns> public static int CreateParallelField(MarcField field, bool bTo880, Delegate_getPinyin getPinyin, out string strError) { strError = ""; if (field.ChildNodes.count == 0) return 1; MarcRecord record = (MarcRecord)field.Parent; MarcField main_field = null; string strFieldName = ""; string strNumber = ""; string strScriptId = ""; string strOrientation = ""; // 观察平行字段是否已经存在? string content_6 = field.select("subfield[@name='6']").FirstContent; if (string.IsNullOrEmpty(content_6) == false) { // 拆解 $6 内容 _parseSubfield6(content_6, out strFieldName, out strNumber, out strScriptId, out strOrientation); if (string.IsNullOrEmpty(strScriptId) == true) { strError = "field 的 $6 表明不是中文的字段,无法创建平行字段"; return 1; } // 找到关联的字段 main_field = _findField(record, strFieldName, field.Name, strNumber); } bool bNewField = false; if (main_field == null) { string strMainFieldName = field.Name; if (field.Name == "880") { // 只能靠 $6 中 linking tag if (string.IsNullOrEmpty(strFieldName) == true) { strError = "当前字段为 880 字段,但没有 $6 子字段,无法获得对应的字段名,因此函数调用失败"; return -1; } strMainFieldName = strFieldName; } main_field = new MarcField(strMainFieldName, field.Indicator, ""); if (field.Name != "880") field.before(main_field); else record.ChildNodes.insertSequence(main_field, InsertSequenceStyle.PreferTail); bNewField = true; } else { // 内容全部删除。只是占用原有位置 main_field.Content = ""; main_field.Indicator = field.Indicator; } if (string.IsNullOrEmpty(strNumber) == true) strNumber = _getNewNumber(record); { // $6 MarcSubfield subfield_6 = new MarcSubfield("6", _buildSubfield6(bTo880 == true? "880" : field.Name, strNumber, "", strOrientation) ); main_field.ChildNodes.add(subfield_6); } int nHanziCount = 0; List<MarcSubfield> remove_subfields = new List<MarcSubfield>(); // 其余子字段逐个加入 foreach (MarcSubfield subfield in field.ChildNodes) { if (subfield.Name == "6") continue; // 2014/10/20 if (subfield.Name == "9" || char.IsUpper(subfield.Name[0]) == true) { remove_subfields.Add(subfield); continue; } string strPinyin = getPinyin(subfield.Content, out strError); if (strPinyin == null) { strError = "创建拼音的过程出错: " + strError; return -1; } if (strPinyin != subfield.Content) nHanziCount++; main_field.ChildNodes.add(new MarcSubfield(subfield.Name, strPinyin)); } // 2014/10/20 if (remove_subfields.Count > 0) { foreach (MarcSubfield subfield in remove_subfields) { subfield.detach(); } } if (nHanziCount == 0 && bNewField == true) { main_field.detach(); return 1; } // 当前字段加入 $6 { if (string.IsNullOrEmpty(strScriptId) == true) strScriptId = "$1"; MarcSubfield subfield_6 = null; MarcNodeList temp = field.select("subfield[@name='6']"); if (temp.count > 0) { subfield_6 = temp[0] as MarcSubfield; subfield_6.Content = _buildSubfield6(main_field.Name, strNumber, strScriptId, strOrientation); } else { subfield_6 = new MarcSubfield("6", _buildSubfield6(main_field.Name, strNumber, strScriptId, strOrientation) ); field.ChildNodes.insert(0, subfield_6); } } if (bTo880) { field.Name = "880"; } return 0; }
// parameters: // strValue 要修改成的值。如果为 null,表示删除这个子字段/部分。如果为 "" 则表示把内容设为空,但子字段还会被保留 // return: // 是否发生了修改 static bool SetSubfield(MarcField field, string strPath, string strValue, ref StringBuilder debug) { if (string.IsNullOrEmpty(strPath) == true || strPath.Length < 1) throw new ArgumentException("strPath 参数值应为一个字符以上", "strPath"); if (strPath == "indicator1") { if (string.IsNullOrEmpty(strValue) == true) throw new ArgumentException("当操作 indicator 的时候, strValue 参数值不允许为空", "strValue"); if (field.Indicator1 == strValue[0]) return false; field.Indicator1 = strValue[0]; return true; } if (strPath == "indicator2") { if (string.IsNullOrEmpty(strValue) == true) throw new ArgumentException("当操作 indicator 的时候, strValue 参数值不允许为空", "strValue"); if (field.Indicator2 == strValue[0]) return false; field.Indicator2 = strValue[0]; return true; } string strSubfieldName = ""; string strPartName = ""; StringUtil.ParseTwoPart(strPath, ".", out strSubfieldName, out strPartName); MarcNodeList subfields = field.select("subfield[@name='" + strSubfieldName + "']"); if (subfields.count == 0) { if (strValue == null) return false; // 正好,也不用删除了 string strContent = strValue; if (string.IsNullOrEmpty(strPartName) == false) strContent = strPartName + ":" + strValue; field.ChildNodes.insertSequence(new MarcSubfield(strSubfieldName, strContent)); debug.Append("新增 <" + strPath + "> '" + strContent + "'\r\n"); return true; } else { // 对整个子字段内容进行操作。只修改第一个子字段内容 if (string.IsNullOrEmpty(strPartName) == true) { if (strValue == null) { subfields[0].detach(); return true; } if (subfields[0].Content == strValue) return false; subfields[0].Content = strValue; return true; } string strContent = subfields[0].Content; ParamList table = ParamList.Build(strContent, ';', ':'); if (strValue == null) table.Remove(strPartName); else table[strPartName] = strValue; string strNewContent = table.ToString(';', ':'); if (strContent == strNewContent) return false; subfields[0].Content = strNewContent; debug.Append("<" + strPartName + "> '" + strContent + "' --> '" + strNewContent + "'\r\n"); return true; } }
// 获得一个子字段内容,或局部内容 // parameters: // strSubfieldName 可能为 "a",也可能为 "x.rights" 形态 static string GetSubfield(MarcField field, string strPath) { if (string.IsNullOrEmpty(strPath) == true || strPath.Length < 1) throw new ArgumentException("strPath 参数值应为一个字符以上", "strPath"); string strSubfieldName = ""; string strPartName = ""; StringUtil.ParseTwoPart(strPath, ".", out strSubfieldName, out strPartName); string strContent = field.select("subfield[@name='"+strSubfieldName+"']").FirstContent; if (string.IsNullOrEmpty(strPartName) == true) return strContent; // 读取参数的时候,不在意内部顺序问题 Hashtable table = StringUtil.ParseParameters(strContent, ';', ':'); return (string)table[strPartName]; }
// 设置 ListViewItem 的各列 void SetItemColumns(ListViewItem item, string strBiblioRecPath, MarcField field, int index) { // 设置各列内容 string u = field.select("subfield[@name='u']").FirstContent; string x = field.select("subfield[@name='x']").FirstContent; // 读取参数的时候,不在意内部顺序问题 Hashtable table = StringUtil.ParseParameters(x, ';', ':'); string strType = (string)table["type"]; string strRights = (string)table["rights"]; string strSize = (string)table["size"]; string strSource = (string)table["source"]; if (string.IsNullOrEmpty(strBiblioRecPath) == false) ListViewUtil.ChangeItemText(item, COLUMN_RECPATH, strBiblioRecPath); ListViewUtil.ChangeItemText(item, COLUMN_FIELDINDEX, index.ToString()); ListViewUtil.ChangeItemText(item, COLUMN_INDICATOR1, field.Indicator1.ToString()); ListViewUtil.ChangeItemText(item, COLUMN_INDICATOR2, field.Indicator2.ToString()); ListViewUtil.ChangeItemText(item, COLUMN_URL, u); ListViewUtil.ChangeItemText(item, COLUMN_F, field.select("subfield[@name='f']").FirstContent); ListViewUtil.ChangeItemText(item, COLUMN_Q, field.select("subfield[@name='q']").FirstContent); ListViewUtil.ChangeItemText(item, COLUMN_S, field.select("subfield[@name='s']").FirstContent); ListViewUtil.ChangeItemText(item, COLUMN_Y, field.select("subfield[@name='y']").FirstContent); ListViewUtil.ChangeItemText(item, COLUMN_Z, field.select("subfield[@name='z']").FirstContent); ListViewUtil.ChangeItemText(item, COLUMN_X, x); ListViewUtil.ChangeItemText(item, COLUMN_RIGHTS, strRights); ListViewUtil.ChangeItemText(item, COLUMN_SIZE, strSize); ListViewUtil.ChangeItemText(item, COLUMN_SOURCE, strSource); ListViewUtil.ChangeItemText(item, COLUMN_TYPE, strType); ListViewUtil.ChangeItemText(item, COLUMN_2, field.select("subfield[@name='2']").FirstContent); ListViewUtil.ChangeItemText(item, COLUMN_3, field.select("subfield[@name='3']").FirstContent); ListViewUtil.ChangeItemText(item, COLUMN_8, field.select("subfield[@name='8']").FirstContent); }