/// <summary> /// 由工作单格式创建 MarcRecord 对象 /// </summary> /// <param name="strText">工作单格式文本。注意子字段符号为 'ǂ'</param> /// <returns>MarcRecord 对象</returns> public static MarcRecord FromWorksheet(string strText) { MarcRecord record = new MarcRecord(); if (string.IsNullOrEmpty(strText)) { return(record); } string[] lines = strText.Replace("\r\n", "\r").Split(new char[] { '\r' }); // 头标区 string first_line = lines[0]; if (first_line.Length < 24) { first_line = first_line.PadRight(24, ' '); } record.Header[0, Math.Min(first_line.Length, 24)] = first_line; int i = 0; foreach (string line in lines) { if (i > 0) { // // record.add(new MarcField("001A1234567")); record.add(new MarcField('ǂ', line)); } i++; } return(record); }
// 构建集合对象 // parameters: // strDef 定义字符串。分为若干行,每行定义一个对照关系。行之间用分号间隔。 // 行格式为 dbname=数据库名,source=源字段名子字段名,target=目标字段名子字段名,color=#000000 public int Build(string strMARC, string strDef, out string strError) { strError = ""; this.MARC = strMARC; MarcRecord record = new MarcRecord(strMARC); string[] lines = strDef.Split(new char[] { ';' }); foreach (string line in lines) { Hashtable table = StringUtil.ParseParameters(line, ',', '='); string strDbName = (string)table["dbname"]; string strSource = (string)table["source"]; string strTarget = (string)table["target"]; string strColor = (string)table["color"]; if (string.IsNullOrEmpty(strSource) == true || strSource.Length != 4) { strError = "行 '" + line + "' 中 source 参数值 '" + strSource + "' 格式错误,应为 4 字符"; return -1; } if (string.IsNullOrEmpty(strTarget) == true || strTarget.Length != 4) { strError = "行 '" + line + "' 中 target 参数值 '" + strTarget + "' 格式错误,应为 4 字符"; return -1; } string fieldname = strSource.Substring(0, 3); string subfieldname = strSource.Substring(3, 1); MarcNodeList subfields = record.select("field[@name='" + fieldname + "']/subfield[@name='" + subfieldname + "']"); if (subfields.count == 0) continue; List<string> keys = new List<string>(); foreach (MarcSubfield subfield in subfields) { if (string.IsNullOrEmpty(subfield.Content) == true) continue; keys.Add(subfield.Content); } if (keys.Count == 0) continue; Relation relation = new Relation(strDbName, strSource, strTarget, keys, strColor); this._collection.Add(relation); } return 0; }
/// <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> /// 创建一个新的 MarcRecord 节点对象,从当前对象复制出全部内容和下级节点 /// </summary> /// <returns>新的节点对象</returns> public override MarcNode clone() { MarcNode new_node = new MarcRecord(); new_node.Text = this.Text; new_node.Parent = null; // 尚未和任何对象连接 return(new_node); }
/// <summary> /// 把记录中的 880 字段聚集在一起 /// </summary> /// <param name="record">MARC 记录</param> public static void PositionField880s(MarcRecord record) { MarcNodeList fields = record.select("field[@name='880']"); fields.detach(); foreach (MarcField field in fields) { record.ChildNodes.insertSequence(field, InsertSequenceStyle.PreferTail); } }
// 给 MARC21 的若干子字段添加正确的标点符号 /// <summary> /// 给 MARC21 的若干子字段添加正确的标点符号 /// </summary> /// <param name="record">MARC 记录</param> /// <param name="strStyle">风格</param> /// <returns>记录是否发生了修改</returns> public static bool PunctuationMarc21(MarcRecord record, string strStyle) { bool bChanged = false; MarcNodeList fields = record.select("field[@name='245']"); foreach (MarcField field in fields) { if (PunctuationMarc21Field245(field, strStyle) == true) { bChanged = true; } } return(bChanged); }
// 根据字段名和 $6 内容寻找字段 // parameters: // strFieldName 要找的字段的字段名 // strFieldName6 $6 子字段里面的字段名 static MarcField _findField( MarcRecord record, string strFieldName, string strFieldName6, string strNumber, bool bMainField = true) { MarcNodeList fields = record.select("field[@name='" + strFieldName + "']"); foreach (MarcField field in fields) { string content_6 = field.select("subfield[@name='6']").FirstContent; if (string.IsNullOrEmpty(content_6) == true) { continue; } // 拆解 $6 内容 string strCurFieldName = ""; string strCurNumber = ""; string strScriptId = ""; string strOrentation = ""; _parseSubfield6(content_6, out strCurFieldName, out strCurNumber, out strScriptId, out strOrentation); if (string.IsNullOrEmpty(strScriptId) == false && bMainField == true) { continue; } if (string.IsNullOrEmpty(strScriptId) == true && bMainField == false) { continue; } if (strCurFieldName == strFieldName6 && strCurNumber == strNumber) { return(field); } } return(null); }
// 获得一个未使用过的字段连接编号 static string _getNewNumber(MarcRecord record) { List <string> numbers = new List <string>(); MarcNodeList subfields = record.select("field/subfield[@name='6']"); foreach (MarcSubfield subfield in subfields) { // 拆解 $6 内容 string strFieldName = ""; string strNumber = ""; string strScriptId = ""; string strOrientation = ""; _parseSubfield6(subfield.Content, out strFieldName, out strNumber, out strScriptId, out strOrientation); if (string.IsNullOrEmpty(strNumber) == false) { numbers.Add(strNumber); } } if (numbers.Count == 0) { return("01"); } numbers.Sort(); string strMaxNumber = numbers[numbers.Count - 1]; int nMax = 0; if (Int32.TryParse(strMaxNumber, out nMax) == false) { throw new Exception("字段编号 '" + strMaxNumber + "' 格式错误,应该为二位数字"); } if (nMax < 0 || nMax > 98) { throw new Exception("已有最大字段编号 '" + strMaxNumber + "' 格式错误,应该为二位数字,值在 00-98 之间"); } return((nMax + 1).ToString().PadLeft(2, '0')); }
public static int ScriptUnimarc( string strRecPath, string strMARC, out List<NameValueLine> results, out string strError) { strError = ""; results = new List<NameValueLine>(); MarcRecord record = new MarcRecord(strMARC); if (record.ChildNodes.count == 0) return 0; // 010 MarcNodeList fields = record.select("field[@name='010' or @name='011' or @name='091']"); if (fields.count > 0) { results.Add(new NameValueLine("获得方式", BuildFields(fields))); } return 0; }
// 2017/4/7 改为用 MarcRecord 处理 100$a // 根据MARC格式类型和输出的编码方式要求,修改MARC记录的头标区或100字段。 // parameters: // strMarcSyntax "unimarc" "usmarc" public static int ModifyOutputMARC( string strMARC, string strMarcSyntax, Encoding encoding, out string strResult) { strResult = strMARC; if (String.Compare(strMarcSyntax, "unimarc", true) == 0) // UNIMARC { /* * In UNIMARC the information about enconding sets are stored in field 100, * position 26-29 & 30-33. The * code for Unicode is "50" in positions 26-27 and the position 28-33 will * contain blanks. */ // 将100字段中28开始的位置按照UTF-8编码特性强行置值。 MarcRecord record = new MarcRecord(strMARC); bool bChanged = false; string strValue = record.select("field[@name='100']/subfield[@name='a']").FirstContent; if (strValue == null) { strValue = ""; } // 确保子字段内容长度为 36 字符。 int nOldLength = strValue.Length; strValue = strValue.PadRight(36, ' '); if (strValue.Length != nOldLength) { bChanged = true; } string strPart = strValue.Substring(26, 8); // 看看26-29是否已经符合要求 if (encoding == Encoding.UTF8) { if (strPart == "50 ") { // 已经符合要求 } else { strValue = strValue.Remove(26, 8); strValue = strValue.Insert(26, "50 "); bChanged = true; } } else { if (strPart == "50 ") { // 需要改变 strValue = strValue.Remove(26, 8); strValue = strValue.Insert(26, "0120 "); bChanged = true; } else { // 不需要改变 } } if (bChanged == true) { record.setFirstSubfield("100", "a", strValue, " "); strResult = record.Text; } } // 修改头标区 if (String.Compare(strMarcSyntax, "unimarc", true) == 0) { // UNIMARC strResult = StringUtil.SetAt(strResult, 9, ' '); } else if (true /*nMARCType == 1*/) { // USMARC。所有非UNIMARC的都仿USMARC处理,因为不必使用100字段 if (encoding == Encoding.UTF8) { strResult = StringUtil.SetAt(strResult, 9, 'a'); // UTF-8(UCS-2也仿此) } else { strResult = StringUtil.SetAt(strResult, 9, ' '); // # DBCS或者MARC-8 // 2007/8/8 change '#' to ' ' } } return(0); }
public void MarcDiff_MergeOldNew_5_6() { string strUserRights = "level-1"; string strFieldNameList = "*:***-***"; // 所有字段都允许操作 MarcRecord old_record = new MarcRecord(); // 旧记录没有 856 字段 old_record.add(new MarcField("001A1234567")); old_record.add(new MarcField('$', "2001 $atitle$fauthor")); old_record.add(new MarcField('$', "701 $aauthor")); MarcRecord new_record = new MarcRecord(); // 新记录增加三个 856 字段 new_record.add(new MarcField("001A1234567")); new_record.add(new MarcField('$', "2001 $atitle$fauthor")); new_record.add(new MarcField('$', "85642$3Cover image 1$uURL1$qimage/jpeg$xtype:FrontCover.SmallImage")); new_record.add(new MarcField('$', "85642$3Cover image 2$uURL2$qimage/jpeg$xtype:FrontCover.MediumImage")); new_record.add(new MarcField('$', "85642$3Cover image 3$uURL3$qimage/jpeg$xtype:FrontCover.LargeImage;rights:group")); new_record.add(new MarcField('$', "701 $aauthor")); MarcRecord target_record = new MarcRecord(); // 结果记录有二个 856 字段。其中一个打算增加的被拒绝了 target_record.add(new MarcField("001A1234567")); target_record.add(new MarcField('$', "2001 $atitle$fauthor")); target_record.add(new MarcField('$', "85642$3Cover image 1$uURL1$qimage/jpeg$xtype:FrontCover.SmallImage")); target_record.add(new MarcField('$', "85642$3Cover image 2$uURL2$qimage/jpeg$xtype:FrontCover.MediumImage")); target_record.add(new MarcField('$', "701 $aauthor")); MarcDiff_MergeOldNew( strUserRights, strFieldNameList, old_record, new_record, target_record, "856!"); }
// 测试 MarcDiff.MergeOldNew() 方法 // parameters: // strCommentCheckList 期望在 strComment 中出现的值,逗号分隔 void MarcDiff_MergeOldNew( string strUserRights, string strFieldNameList, MarcRecord old_record, MarcRecord new_record, MarcRecord target_record, string strCommentCheckList = "") { string strComment = ""; string strError = ""; int nRet = 0; string strOldMarc = old_record.Text; nRet = LibraryApplication.MaskCantGet856( strUserRights, ref strOldMarc, out strError); if (nRet == -1) throw new Exception(strError); // Assert.AreEqual(nRet, 1, "应当是只标记了一个 856 字段"); string strNewMarc = new_record.Text; // 对 strNewMarc 进行过滤,将那些当前用户无法读取的 856 字段删除 // 对 MARC 记录进行过滤,将那些当前用户无法读取的 856 字段删除 // return: // -1 出错 // 其他 滤除的 856 字段个数 nRet = LibraryApplication.MaskCantGet856( strUserRights, ref strNewMarc, out strError); if (nRet == -1) throw new Exception(strError); // Assert.AreEqual(nRet, 0, "应当没有标记任何 856 字段"); // 按照字段修改权限定义,合并新旧两个 MARC 记录 // parameters: // strDefaultOperation insert/replace/delete 之一或者逗号间隔组合 // return: // -1 出错 // 0 成功 // 1 有部分修改要求被拒绝 nRet = MarcDiff.MergeOldNew( "insert,replace,delete", strFieldNameList, strOldMarc, ref strNewMarc, out strComment, out strError); if (nRet == -1) throw new Exception(strError); // 检查 strNewMarc if (strNewMarc != target_record.Text) throw new Exception("和期望的结果不符合"); // 检查 strComment if (string.IsNullOrEmpty(strCommentCheckList) == false) { List<string> texts = StringUtil.SplitList(strCommentCheckList); foreach (string text in texts) { if (text == "{null}") { if (string.IsNullOrEmpty(strComment) == false) throw new Exception("strComment 字符串 '" + strComment + "' 没有期望的那样为空"); continue; } nRet = strComment.IndexOf(text); if (nRet == -1) throw new Exception("strComment 字符串 '" + strComment + "' 中没有包含要求的片段 '" + text + "'"); } } }
public string GetMarc() { MarcRecord record = new MarcRecord(this._header); MarcField current_field_node = null; foreach (EasyLine line in this.Items) { if (line is FieldLine) { FieldLine field = line as FieldLine; MarcField field_node = null; if (field.IsControlField == true) field_node = new MarcField(field.Name, "", field.Content); else field_node = new MarcField(field.Name, field.Indicator, ""); record.ChildNodes.add(field_node); current_field_node = field_node; } else if (line is SubfieldLine) { SubfieldLine subfield = line as SubfieldLine; MarcSubfield subfield_node = new MarcSubfield(subfield.Name, subfield.Content); current_field_node.ChildNodes.add(subfield_node); } } return record.Text; }
// 将从属的书目记录保存到MARC文件 void menu_saveBiblioRecordToMarcFile_Click(object sender, EventArgs e) { string strError = ""; int nRet = 0; if (this.listView_records.SelectedItems.Count == 0) { strError = "尚未选定要保存的事项"; goto ERROR1; } // 为了书目记录路径去重服务 Hashtable biblio_recpath_table = new Hashtable(); Hashtable rule_name_table = null; bool bTableExists = false; // 将馆藏地点名和编目规则名的对照表装入内存 // return: // -1 出错 // 0 文件不存在 // 1 成功 nRet = LoadRuleNameTable(PathUtil.MergePath(this.MainForm.DataDir, "cataloging_rules.xml"), out rule_name_table, out strError); if (nRet == -1) goto ERROR1; if (nRet == 1) bTableExists = true; Debug.Assert(rule_name_table != null, ""); Encoding preferredEncoding = this.CurrentEncoding; { // 观察要保存的第一条记录的marc syntax } OpenMarcFileDlg dlg = new OpenMarcFileDlg(); MainForm.SetControlFont(dlg, this.Font); dlg.IsOutput = true; dlg.AddG01Visible = false; if (bTableExists == false) { dlg.RuleVisible = true; dlg.Rule = this.LastCatalogingRule; } dlg.FileName = this.LastIso2709FileName; dlg.CrLf = this.LastCrLfIso2709; dlg.EncodingListItems = Global.GetEncodingList(false); dlg.EncodingName = (String.IsNullOrEmpty(this.LastEncodingName) == true ? Global.GetEncodingName(preferredEncoding) : this.LastEncodingName); dlg.EncodingComment = "注: 原始编码方式为 " + Global.GetEncodingName(preferredEncoding); dlg.MarcSyntax = "<自动>"; // strPreferedMarcSyntax; dlg.EnableMarcSyntax = false; dlg.ShowDialog(this); if (dlg.DialogResult != DialogResult.OK) return; string strCatalogingRule = ""; if (bTableExists == false) { strCatalogingRule = dlg.Rule; if (strCatalogingRule == "<无限制>") strCatalogingRule = null; } Encoding targetEncoding = null; nRet = Global.GetEncoding(dlg.EncodingName, out targetEncoding, out strError); if (nRet == -1) { goto ERROR1; } string strLastFileName = this.LastIso2709FileName; string strLastEncodingName = this.LastEncodingName; bool bExist = File.Exists(dlg.FileName); bool bAppend = false; if (bExist == true) { DialogResult result = MessageBox.Show(this, "文件 '" + dlg.FileName + "' 已存在,是否以追加方式写入记录?\r\n\r\n--------------------\r\n注:(是)追加 (否)覆盖 (取消)放弃", this.DbType + "SearchForm", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == DialogResult.Yes) bAppend = true; if (result == DialogResult.No) bAppend = false; if (result == DialogResult.Cancel) { strError = "放弃处理..."; goto ERROR1; } } // 检查同一个文件连续存时候的编码方式一致性 if (strLastFileName == dlg.FileName && bAppend == true) { if (strLastEncodingName != "" && strLastEncodingName != dlg.EncodingName) { DialogResult result = MessageBox.Show(this, "文件 '" + dlg.FileName + "' 已在先前已经用 " + strLastEncodingName + " 编码方式存储了记录,现在又以不同的编码方式 " + dlg.EncodingName + " 追加记录,这样会造成同一文件中存在不同编码方式的记录,可能会令它无法被正确读取。\r\n\r\n是否继续? (是)追加 (否)放弃操作", this.DbType + "SearchForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.No) { strError = "放弃处理..."; goto ERROR1; } } } this.LastIso2709FileName = dlg.FileName; this.LastCrLfIso2709 = dlg.CrLf; this.LastEncodingName = dlg.EncodingName; this.LastCatalogingRule = dlg.Rule; this.EnableControls(false); stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在保存到 MARC 文件 ..."); stop.BeginLoop(); Stream s = null; int nOutputCount = 0; try { s = File.Open(this.LastIso2709FileName, FileMode.OpenOrCreate); if (bAppend == false) s.SetLength(0); else s.Seek(0, SeekOrigin.End); } catch (Exception ex) { strError = "打开或创建文件 " + this.LastIso2709FileName + " 失败,原因: " + ex.Message; goto ERROR1; } try { stop.SetProgressRange(0, this.listView_records.SelectedItems.Count); int i = 0; foreach (ListViewItem item in this.listView_records.SelectedItems) { Application.DoEvents(); // 出让界面控制权 if (stop != null) { if (stop.State != 0) { strError = "用户中断"; goto ERROR1; } } string strRecPath = item.Text; if (String.IsNullOrEmpty(strRecPath) == true) goto CONTINUE; stop.SetMessage("正在准备记录 " + strRecPath + " 的书目记录路径 ..."); stop.SetProgressValue(i); string strItemRecPath = ""; string strBiblioRecPath = ""; string strLocation = ""; if (this.DbType == "item") { Debug.Assert(this.DbType == "item", ""); nRet = SearchTwoRecPathByBarcode( this.stop, this.Channel, "@path:" + strRecPath, out strItemRecPath, out strLocation, out strBiblioRecPath, out strError); } else { nRet = SearchBiblioRecPath( this.stop, this.Channel, this.DbType, strRecPath, out strBiblioRecPath, out strError); } if (nRet == -1) { goto ERROR1; } else if (nRet == 0) { strError = "记录路径 '" + strRecPath + "' 没有找到记录"; goto ERROR1; } else if (nRet == 1) { item.Text = strItemRecPath; } else if (nRet > 1) // 命中发生重复 { strError = "记录路径 '" + strRecPath + "' 命中 " + nRet.ToString() + " 条记录,这是一个严重错误"; } // 去重 if (biblio_recpath_table.ContainsKey(strBiblioRecPath) == true) goto CONTINUE; if (bTableExists == true) { strCatalogingRule = ""; // 根据馆藏地点获得编目规则名 if (this.DbType == "item" && string.IsNullOrEmpty(strLocation) == false) { // strCatalogingRule = (string)rule_name_table[strLocation]; if (string.IsNullOrEmpty(strCatalogingRule) == true) { strCatalogingRule = InputDlg.GetInput( this, null, "请输入馆藏地点 '" + strLocation + "' 所对应的编目规则名称:", "NLC", this.MainForm.DefaultFont); if (strCatalogingRule == null) { DialogResult result = MessageBox.Show(this, "由于您没有指定馆藏地点 '" + strLocation + "' 所对应的编目规则名,此馆藏地点被当作 <无限制> 编目规则来处理。\r\n\r\n是否继续操作? (OK 继续;Cancel 放弃整个导出操作)", this.DbType + "SearchForm", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == System.Windows.Forms.DialogResult.Cancel) break; strCatalogingRule = ""; } rule_name_table[strLocation] = strCatalogingRule; // 储存到内存,后面就不再作相同的询问了 } } } string[] results = null; byte[] baTimestamp = null; stop.SetMessage("正在获取书目记录 " + strBiblioRecPath); long lRet = Channel.GetBiblioInfos( stop, strBiblioRecPath, "", new string[] { "xml" }, // formats out results, out baTimestamp, out strError); if (lRet == 0) goto ERROR1; if (lRet == -1) goto ERROR1; if (results == null || results.Length == 0) { strError = "results error"; goto ERROR1; } string strXml = results[0]; string strMARC = ""; string strMarcSyntax = ""; // 将XML格式转换为MARC格式 // 自动从数据记录中获得MARC语法 nRet = MarcUtil.Xml2Marc(strXml, true, null, out strMarcSyntax, out strMARC, out strError); if (nRet == -1) { strError = "XML转换到MARC记录时出错: " + strError; goto ERROR1; } byte[] baTarget = null; Debug.Assert(strMarcSyntax != "", ""); // 按照编目规则过滤 // 获得一个特定风格的 MARC 记录 // parameters: // strStyle 要匹配的style值。如果为null,表示任何$*值都匹配,实际上效果是去除$*并返回全部字段内容 // return: // 0 没有实质性修改 // 1 有实质性修改 nRet = MarcUtil.GetMappedRecord(ref strMARC, strCatalogingRule); if (dlg.RemoveField998 == true) { MarcRecord record = new MarcRecord(strMARC); record.select("field[@name='998']").detach(); strMARC = record.Text; } if (dlg.Mode880 == true && strMarcSyntax == "usmarc") { MarcRecord record = new MarcRecord(strMARC); MarcQuery.To880(record); strMARC = record.Text; } // 将MARC机内格式转换为ISO2709格式 // parameters: // strSourceMARC [in]机内格式MARC记录。 // strMarcSyntax [in]为"unimarc"或"usmarc" // targetEncoding [in]输出ISO2709的编码方式。为UTF8、codepage-936等等 // baResult [out]输出的ISO2709记录。编码方式受targetEncoding参数控制。注意,缓冲区末尾不包含0字符。 // return: // -1 出错 // 0 成功 nRet = MarcUtil.CvtJineiToISO2709( strMARC, strMarcSyntax, targetEncoding, out baTarget, out strError); if (nRet == -1) goto ERROR1; /* Encoding sourceEncoding = connection.GetRecordsEncoding( this.MainForm, record.m_strSyntaxOID); if (sourceEncoding.Equals(targetEncoding) == true) { // source和target编码方式相同,不用转换 baTarget = record.m_baRecord; } else { nRet = ChangeIso2709Encoding( sourceEncoding, record.m_baRecord, targetEncoding, strMarcSyntax, out baTarget, out strError); if (nRet == -1) goto ERROR1; }*/ s.Write(baTarget, 0, baTarget.Length); if (dlg.CrLf == true) { byte[] baCrLf = targetEncoding.GetBytes("\r\n"); s.Write(baCrLf, 0, baCrLf.Length); } stop.SetProgressValue(i + 1); nOutputCount++; CONTINUE: i++; // biblio_recpath_table[strBiblioRecPath] = 1; } } catch (Exception ex) { strError = "写入文件 " + this.LastIso2709FileName + " 失败,原因: " + ex.Message; goto ERROR1; } finally { s.Close(); stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.HideProgress(); this.EnableControls(true); } // if (bAppend == true) MainForm.StatusBarMessage = nOutputCount.ToString() + "条记录成功追加到文件 " + this.LastIso2709FileName + " 尾部"; else MainForm.StatusBarMessage = nOutputCount.ToString() + "条记录成功保存到新文件 " + this.LastIso2709FileName + " 尾部"; return; ERROR1: MessageBox.Show(this, strError); }
// 探测当前用户对一个书目库的访问权限 public static int DetectAccess(LibraryChannel channel, Stop stop, string strBiblioDbName, string strMarcSyntax, out string strBiblioAccess, out string strEntityAccess, out string strError) { strError = ""; strBiblioAccess = ""; strEntityAccess = ""; // 样本记录 MarcRecord record = new MarcRecord(); record.add(new MarcField('$', "001???????")); record.add(new MarcField('$', "200$a书名$f作者")); record.add(new MarcField('$', "701$a作者")); string strXml = ""; int nRet = MarcUtil.Marc2Xml(record.Text, strMarcSyntax, out strXml, out strError); if (nRet == -1) return -1; List<string> biblio_access_list = new List<string>(); List<string> entity_access_list = new List<string>(); // 模拟书目追加写入 string strAction = "simulate_new"; string strPath = strBiblioDbName + "/?"; string strOutputPath = ""; byte[] baNewTimestamp = null; long lRet = channel.SetBiblioInfo( stop, strAction, strPath, "xml", strXml, null, // baTimestamp, "", out strOutputPath, out baNewTimestamp, out strError); if (lRet == -1) { // 注意检查部分允许写入的报错 if (channel.ErrorCode != ErrorCode.AccessDenied) return -1; } else biblio_access_list.Add("append"); // 模拟书目覆盖写入 strAction = "simulate_change"; strPath = strBiblioDbName + "/0"; lRet = channel.SetBiblioInfo( stop, strAction, strPath, "xml", strXml, null, // baTimestamp, "", out strOutputPath, out baNewTimestamp, out strError); if (lRet == -1) { if (channel.ErrorCode != ErrorCode.AccessDenied) return -1; } else { // 注意检查部分允许写入的报错 if (channel.ErrorCode == ErrorCode.PartialDenied) biblio_access_list.Add("partial_overwrite"); else biblio_access_list.Add("overwrite"); } // 模拟书目删除 strAction = "simulate_delete"; strPath = strBiblioDbName + "/0"; lRet = channel.SetBiblioInfo( stop, strAction, strPath, "xml", strXml, null, // baTimestamp, "", out strOutputPath, out baNewTimestamp, out strError); if (lRet == -1) { if (channel.ErrorCode != ErrorCode.AccessDenied) return -1; } else { // 注意检查部分允许写入的报错 if (channel.ErrorCode == ErrorCode.PartialDenied) biblio_access_list.Add("partial_delete"); else biblio_access_list.Add("delete"); } strBiblioAccess = StringUtil.MakePathList(biblio_access_list); // 模拟实体追加写入 EntityInfo info = new EntityInfo(); { XmlDocument item_dom = new XmlDocument(); item_dom.LoadXml("<root />"); info.Style = "simulate"; info.RefID = Guid.NewGuid().ToString(); DomUtil.SetElementText(item_dom.DocumentElement, "parent", "0"); info.OldRecPath = ""; info.OldRecord = ""; info.OldTimestamp = null; info.Action = "new"; info.NewRecPath = ""; info.NewRecord = item_dom.DocumentElement.OuterXml; info.NewTimestamp = null; } EntityInfo[] entities = new EntityInfo[1]; entities[0] = info; EntityInfo[] errorinfos = null; lRet = channel.SetEntities( stop, strPath, entities, out errorinfos, out strError); if (lRet == -1) { List<string> normal_errors = new List<string>(); List<string> accessdenied_errors = new List<string>(); GetErrorInfo(errorinfos, out normal_errors, out accessdenied_errors); if (normal_errors.Count > 0) { strError = StringUtil.MakePathList(normal_errors, " ; "); return -1; } } else { entity_access_list.Add("append"); } // 模拟实体覆盖写入 info.Action = "change"; lRet = channel.SetEntities( stop, strPath, entities, out errorinfos, out strError); if (lRet == -1) { List<string> normal_errors = new List<string>(); List<string> accessdenied_errors = new List<string>(); GetErrorInfo(errorinfos, out normal_errors, out accessdenied_errors); if (normal_errors.Count > 0) { strError = StringUtil.MakePathList(normal_errors, " ; "); return -1; } } else { entity_access_list.Add("overwrite"); } // 模拟实体删除操作 info.Action = "delete"; // 是否要提供旧记录? info.OldRecPath = ""; info.OldRecord = ""; info.OldTimestamp = null; info.NewRecPath = ""; info.NewRecord = ""; info.NewTimestamp = null; lRet = channel.SetEntities( stop, strPath, entities, out errorinfos, out strError); if (lRet == -1) { List<string> normal_errors = new List<string>(); List<string> accessdenied_errors = new List<string>(); GetErrorInfo(errorinfos, out normal_errors, out accessdenied_errors); if (normal_errors.Count > 0) { strError = StringUtil.MakePathList(normal_errors, " ; "); return -1; } } else { entity_access_list.Add("delete"); } strEntityAccess = StringUtil.MakePathList(entity_access_list); return 0; }
// 将记录写入ISO2709文件 int WriteRecordToISO2709File( Stream outputfile, string strDbName, string strID, string strMarc, byte[] body_timestamp, Encoding targetEncoding, bool bOutputCrLf, bool bAddG01, bool bRemove998, out string strError) { int nRet = 0; string strPath = strDbName + "/" + strID; long lStart = outputfile.Position; // 记忆起始位置 ResPath respath = new ResPath(); respath.Url = channel.Url; respath.Path = strPath; // 去除MARC记录中的所有-01字段 // return: // -1 error // 0 not changed // 1 changed nRet = RemoveG01FromMarc(ref strMarc, out strError); if (nRet == -1) return -1; if (bAddG01 == true) { string strDt1000Path = "/" + strDbName + "/ctlno/" + strID.PadLeft(10, '0'); string strTimestamp = ByteArray.GetHexTimeStampString(body_timestamp); nRet = AddG01ToMarc(ref strMarc, strDt1000Path + "|" + strTimestamp, out strError); if (nRet == -1) return -1; } if (bRemove998 == true) { MarcRecord record = new MarcRecord(strMarc); record.select("field[@name='998']").detach(); strMarc = record.Text; } byte[] baResult = null; // 将MARC机内格式转换为ISO2709格式 // parameters: // nMARCType [in]MARC格式类型。0为UNIMARC 1为USMARC // strSourceMARC [in]机内格式MARC记录。 // targetEncoding [in]输出ISO2709的编码方式为 UTF8 codepage-936等等 // baResult [out]输出的ISO2709记录。字符集受nCharset参数控制。 // 注意,缓冲区末尾不包含0字符。 nRet = MarcUtil.CvtJineiToISO2709( strMarc, this.CurMarcSyntax, targetEncoding, out baResult, out strError); if (nRet == -1) return -1; outputfile.Write(baResult, 0, baResult.Length); if (bOutputCrLf == true) { baResult = new byte[2]; baResult[0] = (byte)'\r'; baResult[1] = (byte)'\n'; outputfile.Write(baResult, 0, 2); } return 0; /* ERROR1: return -1; */ }
// 将亚马逊 XML 格式转换为 UNIMARC 格式 // parameters: // strStyle 转换风格。!856 表示不包含 856 字段 public static int AmazonXmlToUNIMARC(XmlNode root, string strStyle, out string strMARC, out string strError) { strMARC = ""; strError = ""; XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable()); nsmgr.AddNamespace("amazon", AmazonSearch.NAMESPACE); MarcRecord record = new MarcRecord(); // *** 001 string strASIN = DomUtil.GetElementText(root, "amazon:ASIN", nsmgr); if (string.IsNullOrEmpty(strASIN) == false) record.ChildNodes.add(new MarcField("001", "ASIN:" + strASIN)); // *** 010 // ISBN #if NO List<string> isbns = GetFieldValues(root, nsmgr, "amazon:ItemAttributes/amazon:ISBN"); if (isbns.Count == 0) isbns = GetFieldValues(root, nsmgr, "amazon:ItemAttributes/amazon:EAN"); #endif List<string> isbns = GetFieldValues(root, nsmgr, "amazon:ItemAttributes/amazon:EAN"); if (isbns.Count == 0) isbns = GetFieldValues(root, nsmgr, "amazon:ItemAttributes/amazon:ISBN"); // Binding List<string> bindings = GetFieldValues(root, nsmgr, "amazon:ItemAttributes/amazon:Binding"); // 价格 List<string> prices = GetPriceValues(root, nsmgr, "amazon:ItemAttributes/amazon:ListPrice"); for (int i = 0; i < Math.Max(isbns.Count, prices.Count); i++) { string isbn = ""; string binding = ""; string price = ""; if (i < isbns.Count) isbn = isbns[i]; if (i < bindings.Count) binding = bindings[i]; if (i < prices.Count) price = prices[i]; MarcField field = new MarcField("010", " "); record.ChildNodes.add(field); if (string.IsNullOrEmpty(isbn) == false) field.ChildNodes.add(new MarcSubfield("a", isbn)); if (string.IsNullOrEmpty(binding) == false && binding != "平装") field.ChildNodes.add(new MarcSubfield("b", binding)); if (string.IsNullOrEmpty(price) == false) field.ChildNodes.add(new MarcSubfield("d", price)); } // 011 List<string> issns = GetFieldValues(root, nsmgr, "amazon:ItemAttributes/amazon:ISSN"); // 200 List<string> titles = GetFieldValues(root, nsmgr, "amazon:ItemAttributes/amazon:Title"); List<Creator> creators = GetCreatorValues(root, nsmgr, "amazon:ItemAttributes/amazon:Creator"); { MarcField field = new MarcField("200", "1 "); record.ChildNodes.add(field); foreach (string title in titles) { field.ChildNodes.add(new MarcSubfield("a", title)); } int i = 0; foreach (Creator creator in creators) { field.ChildNodes.add(new MarcSubfield(i == 0 ? "f" : "g", creator.Name + creator.Role)); i++; } } // 2015/7/19 // 205 List<string> editions = GetFieldValues(root, nsmgr, "amazon:ItemAttributes/amazon:Edition"); foreach (string edition in editions) { MarcField field = new MarcField("205", " "); record.ChildNodes.add(field); field.ChildNodes.add(new MarcSubfield("a", edition)); } // 210 List<string> publishers = GetFieldValues(root, nsmgr, "amazon:ItemAttributes/amazon:Publisher"); List<string> publication_dates = GetFieldValues(root, nsmgr, "amazon:ItemAttributes/amazon:PublicationDate"); { MarcField field = new MarcField("210", " "); record.ChildNodes.add(field); foreach (string s in publishers) { field.ChildNodes.add(new MarcSubfield("c", s)); } foreach (string s in publication_dates) { // 日期字符串需要变换一下 field.ChildNodes.add(new MarcSubfield("d", GetPublishDateString(s))); } } // 215 a d List<string> pages = GetFieldValues(root, nsmgr, "amazon:ItemAttributes/amazon:NumberOfPages"); List<string> heights = GetHeightValues(root, nsmgr, "amazon:ItemAttributes/amazon:PackageDimensions"); { MarcField field = new MarcField("215", " "); record.ChildNodes.add(field); foreach (string s in pages) { field.ChildNodes.add(new MarcSubfield("a", s + "页")); } foreach (string s in heights) { field.ChildNodes.add(new MarcSubfield("d", s)); } } // 2015/7/19 // 330 List<string> reviews = GetCommentValues(root, nsmgr, "amazon:EditorialReviews/amazon:EditorialReview", "内容简介"); if (reviews.Count > 0) { MarcField field = new MarcField("330", " "); record.ChildNodes.add(field); foreach (string review in reviews) { field.ChildNodes.add(new MarcSubfield("a", review)); } } // 2015/7/19 // 610 List<string> subjects = GetFieldValues(root, nsmgr, "amazon:Subjects/amazon:Subject"); if (subjects.Count > 0) { MarcField field = new MarcField("610", "0 "); record.ChildNodes.add(field); foreach (string subject in subjects) { field.ChildNodes.add(new MarcSubfield("a", subject)); } } // 2015/7/19 // 7xx // authors 里面的元素通常已经被 creators 包含,creators 元素多余 authors。 // 转换策略是,把 authors 里的作为 701,creators 里面余下的作为 702 List<Creator> authors = GetCreatorValues(root, nsmgr, "amazon:ItemAttributes/amazon:Author"); foreach (Creator author in authors) { MarcField field = new MarcField("701", " 0"); record.ChildNodes.add(field); field.ChildNodes.add(new MarcSubfield("a", author.Name)); if (string.IsNullOrEmpty(author.Role) == false) field.ChildNodes.add(new MarcSubfield("4", author.Role)); } foreach (Creator creator in creators) { if (IndexOf(authors, creator.Name) != -1) continue; MarcField field = new MarcField("702", " 0"); record.ChildNodes.add(field); field.ChildNodes.add(new MarcSubfield("a", creator.Name)); if (string.IsNullOrEmpty(creator.Role) == false) field.ChildNodes.add(new MarcSubfield("4", creator.Role)); } if (StringUtil.IsInList("!856", strStyle) == false) { // 856 string[] names = new string[] { "SmallImage", "MediumImage", "LargeImage"}; foreach (string name in names) { List<ImageInfo> small_images = GetImageValues(root, nsmgr, "amazon:" + name); foreach (ImageInfo info in small_images) { MarcField field = new MarcField("856", "4 "); record.ChildNodes.add(field); field.ChildNodes.add(new MarcSubfield("3", "Cover image")); field.ChildNodes.add(new MarcSubfield("u", info.Url)); field.ChildNodes.add(new MarcSubfield("q", GetMime(info.Url))); field.ChildNodes.add(new MarcSubfield("x", "type:FrontCover." + name + ";size:" + info.Size + ";source:Amazon:")); // + dlg.SelectedItem.ASIN } } } strMARC = record.Text; return 0; }
// 对 MARC 记录进行过滤,将那些当前用户无法读取的 856 字段删除 // return: // -1 出错 // 其他 滤除的 856 字段个数 public static int RemoveCantGet856( string strUserRights, ref string strMARC, out string strError) { strError = ""; // 只要当前账户具备 writeobject 或 writeres 权限,等于他可以获取任何对象,为了编辑加工的需要 if (StringUtil.IsInList("writeobject", strUserRights) == true || StringUtil.IsInList("writeres", strUserRights) == true) return 0; MarcRecord record = new MarcRecord(strMARC); MarcNodeList fields = record.select("field[@name='856']"); if (fields.count == 0) return 0; List<MarcField> delete_fields = new List<MarcField>(); foreach (MarcField field in fields) { string x = field.select("subfield[@name='x']").FirstContent; if (string.IsNullOrEmpty(x) == true) continue; Hashtable table = StringUtil.ParseParameters(x, ';', ':'); string strObjectRights = (string)table["rights"]; if (string.IsNullOrEmpty(strObjectRights) == true) continue; // 对象是否允许被获取? if (CanGet(strUserRights, strObjectRights) == false) delete_fields.Add(field); } foreach(MarcField field in delete_fields) { field.detach(); } if (delete_fields.Count > 0) strMARC = record.Text; return delete_fields.Count; }
// 对 MARC 记录进行标记,将那些当前用户无法读取的 856 字段打上特殊标记(内码为 1 的字符) // return: // -1 出错 // 其他 滤除的 856 字段个数 public static int MaskCantGet856( string strUserRights, ref string strMARC, out string strError) { strError = ""; if (string.IsNullOrEmpty(strMARC) == true) return 0; // 只要当前账户具备 writeobject 或 writeres 权限,等于他可以获取任何对象,为了编辑加工的需要 if (StringUtil.IsInList("writeobject", strUserRights) == true || StringUtil.IsInList("writeres", strUserRights) == true) return 0; string strMaskChar = new string((char)1, 1); // 在处理前替换记录中可能出现的 (char)1 // 建议在调用本函数前,探测 strMARC 中是否有这个符号,如果有,可能是相关环节检查不严创建了这样的记录,需要进一步检查处理 strMARC = strMARC.Replace(strMaskChar, "*"); MarcRecord record = new MarcRecord(strMARC); MarcNodeList fields = record.select("field[@name='856']"); if (fields.count == 0) return 0; int nCount = 0; foreach (MarcField field in fields) { string x = field.select("subfield[@name='x']").FirstContent; if (string.IsNullOrEmpty(x) == true) continue; Hashtable table = StringUtil.ParseParameters(x, ';', ':'); string strObjectRights = (string)table["rights"]; if (string.IsNullOrEmpty(strObjectRights) == true) continue; // 对象是否允许被获取? if (CanGet(strUserRights, strObjectRights) == false) { field.Content += strMaskChar; nCount++; } } if (nCount > 0) strMARC = record.Text; return nCount; }
public static int Get856Count(string strMARC) { MarcRecord record = new MarcRecord(strMARC); return record.select("field[@name='856']").count; }
// 注意:上级函数RunScript()已经使用了BeginLoop()和EnableControls() // 对每个Iso2709Statis记录进行循环 // return: // 0 普通返回 // 1 要全部中断 int DoLoop(out string strError) { strError = ""; // int nRet = 0; // long lRet = 0; Encoding encoding = null; if (string.IsNullOrEmpty(this._openMarcFileDialog.EncodingName) == true) { strError = "尚未选定 ISO2709 文件的编码方式"; return -1; } if (StringUtil.IsNumber(this._openMarcFileDialog.EncodingName) == true) encoding = Encoding.GetEncoding(Convert.ToInt32(this._openMarcFileDialog.EncodingName)); else encoding = Encoding.GetEncoding(this._openMarcFileDialog.EncodingName); #if NO // 清除错误信息窗口中残余的内容 if (this.ErrorInfoForm != null) { try { this.ErrorInfoForm.HtmlString = "<pre>"; } catch { } } #endif ClearErrorInfoForm(); string strInputFileName = ""; try { strInputFileName = this._openMarcFileDialog.FileName; Stream file = null; try { file = File.Open(strInputFileName, FileMode.Open, FileAccess.Read); } catch (Exception ex) { strError = "打开文件 " + strInputFileName + " 失败: " + ex.Message; return -1; } this.progressBar_records.Minimum = 0; this.progressBar_records.Maximum = (int)file.Length; this.progressBar_records.Value = 0; /* stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在获取ISO2709记录 ..."); stop.BeginLoop(); EnableControls(false); * */ try { int nCount = 0; for (int i = 0; ; i++) { Application.DoEvents(); // 出让界面控制权 if (stop != null) { if (stop.State != 0) { DialogResult result = MessageBox.Show(this, "准备中断。\r\n\r\n确实要中断全部操作? (Yes 全部中断;No 中断循环,但是继续收尾处理;Cancel 放弃中断,继续操作)", "Iso2709StatisForm", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button3); if (result == DialogResult.Yes) { strError = "用户中断"; return -1; } if (result == DialogResult.No) return 0; // 假装loop正常结束 stop.Continue(); // 继续循环 } } string strMARC = ""; // 从ISO2709文件中读入一条MARC记录 // return: // -2 MARC格式错 // -1 出错 // 0 正确 // 1 结束(当前返回的记录有效) // 2 结束(当前返回的记录无效) int nRet = MarcUtil.ReadMarcRecord(file, encoding, true, // bRemoveEndCrLf, true, // bForce, out strMARC, out strError); if (nRet == -2 || nRet == -1) { DialogResult result = MessageBox.Show(this, "读入MARC记录(" + nCount.ToString() + ")出错: " + strError + "\r\n\r\n确实要中断当前批处理操作?", "Iso2709StatisForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.Yes) { break; } else { strError = "读入MARC记录(" + nCount.ToString() + ")出错: " + strError; GetErrorInfoForm().WriteHtml(strError + "\r\n"); continue; } } if (nRet != 0 && nRet != 1) return 0; // 结束 stop.SetMessage("正在获取第 " + (i + 1).ToString() + " 个 ISO2709 记录"); this.progressBar_records.Value = (int)file.Position; // 跳过太短的记录 if (string.IsNullOrEmpty(strMARC) == true || strMARC.Length <= 24) continue; if (this._openMarcFileDialog.Mode880 == true && (this._openMarcFileDialog.MarcSyntax == "usmarc" || this._openMarcFileDialog.MarcSyntax == "<自动>")) { MarcRecord temp = new MarcRecord(strMARC); MarcQuery.ToParallel(temp); strMARC = temp.Text; } // 触发Script中OnRecord()代码 if (objStatis != null) { objStatis.MARC = strMARC; objStatis.CurrentRecordIndex = i; StatisEventArgs args = new StatisEventArgs(); objStatis.OnRecord(this, args); if (args.Continue == ContinueType.SkipAll) return 1; if (args.Continue == ContinueType.Error) { strError = args.ParamString; return -1; } } nCount++; } /* Global.WriteHtml(this.webBrowser_batchAddItemPrice, "处理结束。共增补价格字符串 " + nCount.ToString() + " 个。\r\n"); * */ return 0; } finally { /* EnableControls(true); stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); * */ if (file != null) file.Close(); } } finally { } // return 0; }
public int LinkMarcFile() { OpenMarcFileDlg dlg = new OpenMarcFileDlg(); GuiUtil.SetControlFont(dlg, this.Font); dlg.IsOutput = false; dlg.GetEncoding -= new GetEncodingEventHandler(dlg_GetEncoding); dlg.GetEncoding += new GetEncodingEventHandler(dlg_GetEncoding); dlg.FileName = this.MainForm.LinkedMarcFileName; // dlg.CrLf = MainForm.LastCrLfIso2709; dlg.EncodingListItems = Global.GetEncodingList(true); // dlg.EncodingName = ""; GetEncodingForm.GetEncodingName(preferredEncoding); // dlg.EncodingComment = "注: 原始编码方式为 " + GetEncodingForm.GetEncodingName(preferredEncoding); // dlg.MarcSyntax = "<自动>"; // strPreferedMarcSyntax; dlg.EnableMarcSyntax = true; if (String.IsNullOrEmpty(this.MainForm.LinkedEncodingName) == false) dlg.EncodingName = this.MainForm.LinkedEncodingName; if (String.IsNullOrEmpty(this.MainForm.LinkedMarcSyntax) == false) dlg.MarcSyntax = this.MainForm.LinkedMarcSyntax; this.MainForm.AppInfo.LinkFormState(dlg, "OpenMarcFileDlg_state"); dlg.ShowDialog(this); if (dlg.DialogResult != DialogResult.OK) return 0; // 储存用过的文件名 // 2009/9/21 this.MainForm.LinkedMarcFileName = dlg.FileName; this.MainForm.LinkedEncodingName = dlg.EncodingName; this.MainForm.LinkedMarcSyntax = dlg.MarcSyntax; string strError = ""; this.linkMarcFile = new LinkMarcFile(); int nRet = this.linkMarcFile.Open(dlg.FileName, out strError); if (nRet == -1) goto ERROR1; this.linkMarcFile.Encoding = dlg.Encoding; this.linkMarcFile.MarcSyntax = dlg.MarcSyntax; string strMarc = ""; byte[] baRecord = null; // 2 结束(当前返回的记录无效) nRet = this.linkMarcFile.NextRecord(out strMarc, out baRecord, out strError); if (nRet == -1) goto ERROR1; // 2013/5/26 if (nRet == 2) goto ERROR1; if (this.linkMarcFile.MarcSyntax == "<自动>" || this.linkMarcFile.MarcSyntax.ToLower() == "<auto>") { // 自动识别MARC格式 string strOutMarcSyntax = ""; // 探测记录的MARC格式 unimarc / usmarc / reader // return: // 0 没有探测出来。strMarcSyntax为空 // 1 探测出来了 nRet = MarcUtil.DetectMarcSyntax(strMarc, out strOutMarcSyntax); this.linkMarcFile.MarcSyntax = strOutMarcSyntax; // 有可能为空,表示探测不出来 if (String.IsNullOrEmpty(this.linkMarcFile.MarcSyntax) == true) { MessageBox.Show(this, "软件无法确定此MARC文件的MARC格式"); } } if (dlg.Mode880 == true && linkMarcFile.MarcSyntax == "usmarc") { MarcRecord temp = new MarcRecord(strMarc); MarcQuery.ToParallel(temp); strMarc = temp.Text; } LoadLinkedMarcRecord(strMarc, baRecord); return 0; ERROR1: MessageBox.Show(this, strError); return -1; }
RegisterBiblioInfo BuildBlankBiblioInfo(string strISBN) { // 获得一个可以保存新书目记录的服务器地址和书目库名 string strServerName = ""; string strBiblioDbName = ""; // 寻找一个可以创建新书目记录的数据库信息 // return: // false 没有找到 // ture 找到 GetTargetDatabaseInfo(out strServerName, out strBiblioDbName); // 装入一条空白书目记录 RegisterBiblioInfo info = new RegisterBiblioInfo(); #if NO if (string.IsNullOrEmpty(strBiblioDbName) == false) info.RecPath = strBiblioDbName + "/?@" + strServerName; #endif info.MarcSyntax = "unimarc"; MarcRecord record = new MarcRecord(); record.add(new MarcField('$', "010 $a" + strISBN + "$dCNY??")); record.add(new MarcField('$', "2001 $a$f")); record.add(new MarcField('$', "210 $a$c$d")); record.add(new MarcField('$', "215 $a$d??cm")); record.add(new MarcField('$', "690 $a")); record.add(new MarcField('$', "701 $a")); info.OldXml = record.Text; return info; }
static int ScriptMarc21(string strMARC, out List<NameValueLine> results, out string strError) { strError = ""; results = new List<NameValueLine>(); MarcRecord record = new MarcRecord(strMARC); if (record.ChildNodes.count == 0) return 0; // LC control no. MarcNodeList nodes = record.select("field[@name='010']/subfield[@name='a']"); if (nodes.count > 0) { results.Add(new NameValueLine("LC control no.", nodes[0].Content.Trim())); } // Type of material results.Add(new NameValueLine("Type of material", GetMaterialType(record))); // Personal name MarcNodeList fields = record.select("field[@name='100']"); foreach (MarcNode field in fields) { nodes = field.select("subfield"); if (nodes.count > 0) { results.Add(new NameValueLine("Personal name", ConcatSubfields(nodes))); } } // Corporate name fields = record.select("field[@name='110']"); if (fields.count > 0) { results.Add(new NameValueLine("Corporate name", BuildFields(fields))); } // Uniform title fields = record.select("field[@name='240']"); if (fields.count > 0) { results.Add(new NameValueLine("Uniform title", BuildFields(fields))); } // Main title fields = record.select("field[@name='245']"); if (fields.count > 0) { results.Add(new NameValueLine("Main title", BuildFields(fields))); } #if NO foreach (MarcNode field in fields) { nodes = field.select("subfield"); if (nodes.count > 0) { results.Add(new OneLine("Main title", ConcatSubfields(nodes))); } } #endif // Portion of title fields = record.select("field[@name='246' and @indicator2='0']"); if (fields.count > 0) { results.Add(new NameValueLine("Portion of title", BuildFields(fields))); } // Spine title fields = record.select("field[@name='246' and @indicator2='8']"); if (fields.count > 0) { results.Add(new NameValueLine("Spine title", BuildFields(fields))); } // Edition fields = record.select("field[@name='250']"); if (fields.count > 0) { results.Add(new NameValueLine("Edition", BuildFields(fields))); } // Published/Created fields = record.select("field[@name='260']"); foreach (MarcNode field in fields) { nodes = field.select("subfield"); if (nodes.count > 0) { results.Add(new NameValueLine("Published/Created", ConcatSubfields(nodes))); } } // Related names fields = record.select("field[@name='700' or @name='710' or @name='711']"); if (fields.count > 0) { results.Add(new NameValueLine("Related names", BuildFields(fields))); } // Related titles fields = record.select("field[@name='730' or @name='740']"); if (fields.count > 0) { results.Add(new NameValueLine("Related titles", BuildFields(fields))); } // Description fields = record.select("field[@name='300' or @name='362']"); if (fields.count > 0) { results.Add(new NameValueLine("Description", BuildFields(fields))); } // ISBN fields = record.select("field[@name='020']"); if (fields.count > 0) { results.Add(new NameValueLine("ISBN", BuildFields(fields))); } // Current frequency fields = record.select("field[@name='310']"); if (fields.count > 0) { results.Add(new NameValueLine("Current frequency", BuildFields(fields))); } // Former title fields = record.select("field[@name='247']"); if (fields.count > 0) { results.Add(new NameValueLine("Former title", BuildFields(fields))); } // Former frequency fields = record.select("field[@name='321']"); if (fields.count > 0) { results.Add(new NameValueLine("Former frequency", BuildFields(fields))); } // Continues fields = record.select("field[@name='780']"); if (fields.count > 0) { results.Add(new NameValueLine("Continues", BuildFields(fields))); } // ISSN MarcNodeList subfields = record.select("field[@name='022']/subfield[@name='a']"); if (subfields.count > 0) { results.Add(new NameValueLine("ISSN", ConcatSubfields(subfields))); } // Linking ISSN subfields = record.select("field[@name='022']/subfield[@name='l']"); if (subfields.count > 0) { results.Add(new NameValueLine("Linking ISSN", ConcatSubfields(subfields))); } // Invalid LCCN subfields = record.select("field[@name='010']/subfield[@name='z']"); if (subfields.count > 0) { results.Add(new NameValueLine("Invalid LCCN", ConcatSubfields(subfields))); } // Contents fields = record.select("field[@name='505' and @indicator1='0']"); if (fields.count > 0) { results.Add(new NameValueLine("Contents", BuildFields(fields))); } // Partial contents fields = record.select("field[@name='505' and @indicator1='2']"); if (fields.count > 0) { results.Add(new NameValueLine("Partial contents", BuildFields(fields))); } // Computer file info fields = record.select("field[@name='538']"); if (fields.count > 0) { results.Add(new NameValueLine("Computer file info", BuildFields(fields))); } // Notes fields = record.select("field[@name='500' or @name='501' or @name='504' or @name='561' or @name='583' or @name='588' or @name='590']"); if (fields.count > 0) { results.Add(new NameValueLine("Notes", BuildFields(fields))); } // References fields = record.select("field[@name='510']"); if (fields.count > 0) { results.Add(new NameValueLine("References", BuildFields(fields))); } // Additional formats fields = record.select("field[@name='530' or @name='533' or @name='776']"); if (fields.count > 0) { results.Add(new NameValueLine("Additional formats", BuildFields(fields))); } // Subjects fields = record.select("field[@name='600' or @name='610' or @name='630' or @name='650' or @name='651']"); if (fields.count > 0) { results.Add(new NameValueLine("Subjects", BuildSubjects(fields))); } // Form/Genre fields = record.select("field[@name='655']"); if (fields.count > 0) { results.Add(new NameValueLine("Form/Genre", BuildSubjects(fields))); } // Series fields = record.select("field[@name='440' or @name='490' or @name='830']"); if (fields.count > 0) { results.Add(new NameValueLine("Series", BuildFields(fields))); } // LC classification fields = record.select("field[@name='050']"); if (fields.count > 0) { results.Add(new NameValueLine("LC classification", BuildFields(fields))); } #if NO foreach (MarcNode field in fields) { nodes = field.select("subfield"); if (nodes.count > 0) { results.Add(new OneLine("LC classification", ConcatSubfields(nodes))); } } #endif // NLM class no. fields = record.select("field[@name='060']"); if (fields.count > 0) { results.Add(new NameValueLine("NLM class no.", BuildFields(fields))); } // Dewey class no. // 不要 $2 fields = record.select("field[@name='082']"); if (fields.count > 0) { results.Add(new NameValueLine("Dewey class no.", BuildFields(fields, "a"))); } // NAL class no. fields = record.select("field[@name='070']"); if (fields.count > 0) { results.Add(new NameValueLine("NAL class no.", BuildFields(fields))); } // National bib no. fields = record.select("field[@name='015']"); if (fields.count > 0) { results.Add(new NameValueLine("National bib no.", BuildFields(fields, "a"))); } // National bib agency no. fields = record.select("field[@name='016']"); if (fields.count > 0) { results.Add(new NameValueLine("National bib agency no.", BuildFields(fields, "a"))); } // LC copy fields = record.select("field[@name='051']"); if (fields.count > 0) { results.Add(new NameValueLine("LC copy", BuildFields(fields))); } // Other system no. fields = record.select("field[@name='035'][subfield[@name='a']]"); if (fields.count > 0) { results.Add(new NameValueLine("Other system no.", BuildFields(fields, "a"))); } #if NO fields = record.select("field[@name='035']"); foreach (MarcNode field in fields) { nodes = field.select("subfield[@name='a']"); if (nodes.count > 0) { results.Add(new OneLine("Other system no.", ConcatSubfields(nodes))); } } #endif // Reproduction no./Source fields = record.select("field[@name='037']"); if (fields.count > 0) { results.Add(new NameValueLine("Reproduction no./Source", BuildFields(fields))); } // Geographic area code fields = record.select("field[@name='043']"); if (fields.count > 0) { results.Add(new NameValueLine("Geographic area code", BuildFields(fields))); } // Quality code fields = record.select("field[@name='042']"); if (fields.count > 0) { results.Add(new NameValueLine("Quality code", BuildFields(fields))); } // Links fields = record.select("field[@name='856'or @name='859']"); if (fields.count > 0) { results.Add(new NameValueLine("Links", BuildLinks(fields))); } // Content type fields = record.select("field[@name='336']"); if (fields.count > 0) { results.Add(new NameValueLine("Content type", BuildFields(fields, "a"))); } // Media type fields = record.select("field[@name='337']"); if (fields.count > 0) { results.Add(new NameValueLine("Media type", BuildFields(fields, "a"))); } // Carrier type fields = record.select("field[@name='338']"); if (fields.count > 0) { results.Add(new NameValueLine("Carrier type", BuildFields(fields, "a"))); } return 0; }
// 构造一条空白书目记录 RegisterBiblioInfo BuildBlankBiblioInfo( string strRecord, string strFrom, string strValue) { #if NO // 获得一个可以保存新书目记录的服务器地址和书目库名 string strServerName = ""; string strBiblioDbName = ""; // 寻找一个可以创建新书目记录的数据库信息 // return: // false 没有找到 // ture 找到 GetTargetDatabaseInfo(out strServerName, out strBiblioDbName); #endif // 装入一条空白书目记录 RegisterBiblioInfo info = new RegisterBiblioInfo(); #if NO if (string.IsNullOrEmpty(strBiblioDbName) == false) info.RecPath = strBiblioDbName + "/?@" + strServerName; #endif string strISBN = ""; string strTitle = ""; string strAuthor = ""; string strPublisher = ""; strFrom = strFrom.ToLower(); if (strFrom == "isbn") strISBN = strValue; if (strFrom == "书名" || strFrom == "题名") strTitle = strValue; if (strFrom == "作者" || strFrom == "著者" || strFrom == "责任者") strAuthor = strValue; if (strFrom == "出版者" || strFrom == "出版社") strPublisher = strValue; info.MarcSyntax = "unimarc"; MarcRecord record = new MarcRecord(strRecord); if (string.IsNullOrEmpty(strRecord) == true) { record.add(new MarcField('$', "010 $a" + strISBN + "$dCNY??")); record.add(new MarcField('$', "2001 $a"+strTitle+"$f"+strAuthor)); record.add(new MarcField('$', "210 $a$c"+strPublisher+"$d")); record.add(new MarcField('$', "215 $a$d??cm")); record.add(new MarcField('$', "690 $a")); record.add(new MarcField('$', "701 $a" + strAuthor)); // record.Header.ForceUNIMARCHeader(); record.Header[0, 24] = "?????nam0 22?????3i 45 "; } else { record.setFirstSubfield("010", "a", strISBN); record.setFirstSubfield("200", "a", strTitle); record.setFirstSubfield("200", "f", strAuthor); record.setFirstSubfield("210", "c", strPublisher); record.setFirstSubfield("701", "a", strAuthor); #if NO if (record.select("field[@name='010']").count == 0) record.ChildNodes.insertSequence(new MarcField('$', "010 $a" + strISBN + "$dCNY??")); else if (record.select("field[@name='010']/subfield[@name='a']").count == 0) (record.select("field[@name='010']")[0] as MarcField).ChildNodes.insertSequence(new MarcSubfield("a", strISBN)); else record.select("field[@name='010']/subfield[@name='a']")[0].Content = strISBN; #endif } // info.OldXml = record.Text; string strError = ""; string strXml = ""; int nRet = MarcUtil.Marc2Xml(record.Text, info.MarcSyntax, out strXml, out strError); if (nRet == -1) throw new Exception(strError); info.OldXml = strXml; return info; }
/// <summary> /// 从 MARC 字符串中获得主题词信息 /// </summary> /// <param name="strMARC">MARC 字符串。机内格式</param> /// <param name="strMarcSyntax">MARC 格式</param> /// <param name="reserve_subjects">返回要保留的主题词集合。字段指示符1 不为空的</param> /// <param name="subjects">返回主题词集合。字段指示符1 为空的</param> /// <param name="strError">返回出错信息</param> /// <returns>-1: 出错; 0: 成功</returns> public static int GetSubjectInfo(string strMARC, string strMarcSyntax, out List<string> reserve_subjects, out List<string> subjects, out string strError) { strError = ""; reserve_subjects = new List<string>(); subjects = new List<string>(); MarcRecord record = new MarcRecord(strMARC); MarcNodeList nodes = null; if (strMarcSyntax == "unimarc") nodes = record.select("field[@name='610']/subfield[@name='a']"); else if (strMarcSyntax == "usmarc") nodes = record.select("field[@name='653']/subfield[@name='a']"); else { strError = "未知的 MARC 格式类型 '" + strMarcSyntax + "'"; return -1; } foreach (MarcNode node in nodes) { if (string.IsNullOrEmpty(node.Content.Trim()) == true) continue; Debug.Assert(node.NodeType == NodeType.Subfield, ""); if (node.Parent.Indicator1 == ' ') subjects.Add(node.Content.Trim()); else reserve_subjects.Add(node.Content.Trim()); } return 0; }
// 将原始记录保存到ISO2709文件 // TODO: 如果记录发生了修改,则不再保存原始记录,而要保存MARC编辑器中的记录? public void SaveOriginRecordToIso2709() { string strError = ""; int nRet = 0; byte[] baTarget = null; // 如果已经是ISO2709格式,则存储在这里 string strMarc = ""; // 如果是MARC机内格式,存储在这里 // 如果不是从Z39.50协议过来的记录,或者记录在MARC编辑窗中已经修改过 if (this.m_currentRecord == null || (this.m_currentRecord != null && this.m_currentRecord.m_baRecord == null) // 2008/4/14 || this.MarcEditor.Changed == true) { // strError = "没有当前记录"; // goto ERROR1; // 从MARC编辑器中取记录 strMarc = this.MarcEditor.Marc; baTarget = null; } else { strMarc = ""; baTarget = this.m_currentRecord.m_baRecord; } Encoding preferredEncoding = this.CurrentEncoding; OpenMarcFileDlg dlg = new OpenMarcFileDlg(); GuiUtil.SetControlFont(dlg, this.Font); dlg.IsOutput = true; dlg.GetEncoding -= new GetEncodingEventHandler(dlg_GetEncoding); dlg.GetEncoding += new GetEncodingEventHandler(dlg_GetEncoding); dlg.FileName = MainForm.LastIso2709FileName; dlg.CrLf = MainForm.LastCrLfIso2709; dlg.RemoveField998 = MainForm.LastRemoveField998; dlg.EncodingListItems = Global.GetEncodingList(true); dlg.EncodingName = (String.IsNullOrEmpty(MainForm.LastEncodingName) == true ? GetEncodingForm.GetEncodingName(preferredEncoding) : MainForm.LastEncodingName); dlg.EncodingComment = "注: 原始编码方式为 " + GetEncodingForm.GetEncodingName(preferredEncoding); dlg.MarcSyntax = "<自动>"; // strPreferedMarcSyntax; dlg.EnableMarcSyntax = false; dlg.ShowDialog(this); if (dlg.DialogResult != DialogResult.OK) return; Encoding targetEncoding = null; if (dlg.EncodingName == "MARC-8" && preferredEncoding.Equals(this.MainForm.Marc8Encoding) == false) { strError = "保存操作无法进行。只有在记录的原始编码方式为 MARC-8 时,才能使用这个编码方式保存记录。"; goto ERROR1; } nRet = this.MainForm.GetEncoding(dlg.EncodingName, out targetEncoding, out strError); if (nRet == -1) { goto ERROR1; } string strLastFileName = MainForm.LastIso2709FileName; string strLastEncodingName = MainForm.LastEncodingName; bool bExist = File.Exists(dlg.FileName); bool bAppend = false; if (bExist == true) { DialogResult result = MessageBox.Show(this, "文件 '" + dlg.FileName + "' 已存在,是否以追加方式写入记录?\r\n\r\n--------------------\r\n注:(是)追加 (否)覆盖 (取消)放弃", "ZSearchForm", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == DialogResult.Yes) bAppend = true; if (result == DialogResult.No) bAppend = false; if (result == DialogResult.Cancel) { strError = "放弃处理..."; goto ERROR1; } } // 检查同一个文件连续存时候的编码方式一致性 if (strLastFileName == dlg.FileName && bAppend == true) { if (strLastEncodingName != "" && strLastEncodingName != dlg.EncodingName) { DialogResult result = MessageBox.Show(this, "文件 '" + dlg.FileName + "' 已在先前已经用 " + strLastEncodingName + " 编码方式存储了记录,现在又以不同的编码方式 " + dlg.EncodingName + " 追加记录,这样会造成同一文件中存在不同编码方式的记录,可能会令它无法被正确读取。\r\n\r\n是否继续? (是)追加 (否)放弃操作", "ZSearchForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.No) { strError = "放弃处理..."; goto ERROR1; } } } MainForm.LastIso2709FileName = dlg.FileName; MainForm.LastCrLfIso2709 = dlg.CrLf; MainForm.LastEncodingName = dlg.EncodingName; MainForm.LastRemoveField998 = dlg.RemoveField998; Stream s = null; try { s = File.Open(MainForm.LastIso2709FileName, FileMode.OpenOrCreate); if (bAppend == false) s.SetLength(0); else s.Seek(0, SeekOrigin.End); } catch (Exception ex) { strError = "打开或创建文件 " + MainForm.LastIso2709FileName + " 失败,原因: " + ex.Message; goto ERROR1; } try { string strMarcSyntax = ""; // 当源和目标编码不同的时候,才需要获得MARC语法参数 if (this.CurrentEncoding.Equals(targetEncoding) == false || strMarc != "") { string strMarcSyntaxOID = this.GetCurrentMarcSyntaxOID(out strError); if (String.IsNullOrEmpty(strMarcSyntaxOID) == true) { strError = "当前MARC syntax OID为空,无法判断MARC具体格式"; goto ERROR1; } if (strMarcSyntaxOID == "1.2.840.10003.5.1") strMarcSyntax = "unimarc"; if (strMarcSyntaxOID == "1.2.840.10003.5.10") strMarcSyntax = "usmarc"; } if (strMarc != "") { Debug.Assert(strMarcSyntax != "", ""); if (dlg.RemoveField998 == true) { MarcRecord temp = new MarcRecord(strMarc); temp.select("field[@name='998']").detach(); strMarc = temp.Text; } if (dlg.Mode880 == true && strMarcSyntax == "usmarc") { MarcRecord temp = new MarcRecord(strMarc); MarcQuery.To880(temp); strMarc = temp.Text; } // 将MARC机内格式转换为ISO2709格式 // parameters: // strSourceMARC [in]机内格式MARC记录。 // strMarcSyntax [in]为"unimarc"或"usmarc" // targetEncoding [in]输出ISO2709的编码方式。为UTF8、codepage-936等等 // baResult [out]输出的ISO2709记录。编码方式受targetEncoding参数控制。注意,缓冲区末尾不包含0字符。 // return: // -1 出错 // 0 成功 nRet = MarcUtil.CvtJineiToISO2709( strMarc, strMarcSyntax, targetEncoding, out baTarget, out strError); if (nRet == -1) goto ERROR1; } else if (this.CurrentEncoding.Equals(targetEncoding) == true) { // source和target编码方式相同,不用转换 // baTarget = this.CurrentRecord.m_baRecord; Debug.Assert(strMarcSyntax == "", ""); // 规范化 ISO2709 物理记录 // 主要是检查里面的记录结束符是否正确,去掉多余的记录结束符 baTarget = MarcUtil.CononicalizeIso2709Bytes(targetEncoding, baTarget); } else { // baTarget = this.CurrentRecord.m_baRecord; Debug.Assert(strMarcSyntax != "", ""); nRet = ZSearchForm.ChangeIso2709Encoding( this.CurrentEncoding, baTarget, targetEncoding, strMarcSyntax, out baTarget, out strError); if (nRet == -1) goto ERROR1; } s.Seek(0, SeekOrigin.End); s.Write(baTarget, 0, baTarget.Length); if (dlg.CrLf == true) { byte[] baCrLf = targetEncoding.GetBytes("\r\n"); s.Write(baCrLf, 0, baCrLf.Length); } if (bAppend == true) MainForm.MessageText = "1条记录成功追加到文件 " + MainForm.LastIso2709FileName + " 尾部"; else MainForm.MessageText = "1条记录成功保存到新文件 " + MainForm.LastIso2709FileName + " 尾部"; } catch (Exception ex) { strError = "写入文件 " + MainForm.LastIso2709FileName + " 失败,原因: " + ex.Message; goto ERROR1; } finally { s.Close(); } return; ERROR1: MessageBox.Show(this, strError); }
// 转换为 880 模式 void menuItem_to880(object sender, EventArgs e) { string strMARC = this.Marc; MarcRecord record = new MarcRecord(strMARC); MarcQuery.To880(record); this.Marc = record.Text; }
static string GetMaterialType(MarcRecord record) { if ("at".IndexOf(record.Header[6]) != -1 && "acdm".IndexOf(record.Header[7]) != -1) return "Book"; // Books if (record.Header[6] == "m") return "Computer Files"; if ("df".IndexOf(record.Header[6]) != -1) return "Map"; // Maps if ("cdij".IndexOf(record.Header[6]) != -1) return "Music"; // Music if ("a".IndexOf(record.Header[6]) != -1 && "bis".IndexOf(record.Header[7]) != -1) return "Periodical or Newspaper"; // Continuing Resources if ("gkor".IndexOf(record.Header[6]) != -1) return "Visual Material"; // Visual Materials if (record.Header[6] == "p") return "Mixed Material"; // Mixed Materials return ""; }
/// <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> /// 根据提供的主题词字符串 修改 MARC 记录中的 610 或 653 字段 /// </summary> /// <param name="strMARC">要操作的 MARC 记录字符串。机内格式</param> /// <param name="strMarcSyntax">MARC 格式</param> /// <param name="subjects">主题词字符串集合</param> /// <param name="strError">返回出错信息</param> /// <returns>-1: 出错; 0: 成功</returns> public static int ChangeSubject(ref string strMARC, string strMarcSyntax, List<string> subjects, out string strError) { strError = ""; MarcRecord record = new MarcRecord(strMARC); MarcNodeList nodes = null; if (strMarcSyntax == "unimarc") nodes = record.select("field[@name='610' and @indicator1=' ']"); else if (strMarcSyntax == "usmarc") nodes = record.select("field[@name='653' and @indicator1=' ']"); else { strError = "未知的 MARC 格式类型 '" + strMarcSyntax + "'"; return -1; } if (subjects == null || subjects.Count == 0) { // 删除那些可以删除的 610 字段 foreach (MarcNode node in nodes) { MarcNodeList subfields = node.select("subfield[@name='a']"); if (subfields.count == node.ChildNodes.count) { // 如果除了 $a 以外没有其他任何子字段,则字段可以删除 node.detach(); } } } else { MarcNode field610 = null; // 只留下一个 610 字段 if (nodes.count > 1) { int nCount = nodes.count; foreach (MarcNode node in nodes) { MarcNodeList subfields = node.select("subfield[@name='a']"); if (subfields.count == node.ChildNodes.count) { // 如果除了 $a 以外没有其他任何子字段,则字段可以删除 node.detach(); nCount--; } if (nCount <= 1) break; } // 重新选定 if (strMarcSyntax == "unimarc") nodes = record.select("field[@name='610' and @indicator1=' ']"); else if (strMarcSyntax == "usmarc") nodes = record.select("field[@name='653' and @indicator1=' ']"); field610 = nodes[0]; } else if (nodes.count == 0) { // 创建一个新的 610 字段 if (strMarcSyntax == "unimarc") field610 = new MarcField("610", " "); else if (strMarcSyntax == "usmarc") field610 = new MarcField("653", " "); record.ChildNodes.insertSequence(field610); } else { Debug.Assert(nodes.count == 1, ""); field610 = nodes[0]; } // 删除全部 $a 子字段 field610.select("subfield[@name='a']").detach(); // 添加若干个 $a 子字段 Debug.Assert(subjects.Count > 0, ""); MarcNodeList source = new MarcNodeList(); for (int i = 0; i < subjects.Count; i++) { source.add(new MarcSubfield("a", subjects[i])); } // 寻找适当位置插入 field610.ChildNodes.insertSequence(source[0]); if (source.count > 1) { // 在刚插入的对象后面插入其余的对象 MarcNodeList list = new MarcNodeList(source[0]); source.removeAt(0); // 排除刚插入的一个 list.after(source); } } strMARC = record.Text; return 0; }
/// <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); }
// 设置 MARC 记录内容 public void SetMarc(string strMarc) { this.Clear(); this.MarcDefDom = null; // 迫使重新获得字段名提示信息 this.DisableUpdate(); try { int nLineIndex = 0; MarcRecord record = new MarcRecord(strMarc); this._header = record.Header.ToString(); // 头标区 foreach (MarcField field in record.ChildNodes) { FieldLine field_line = new FieldLine(this); field_line.Name = field.Name; field_line.Caption = GetCaption(field.Name, "", this._includeNumber); // field_line.Indicator = field.Indicator; InsertNewLine(nLineIndex++, field_line, false); field_line.IsControlField = field.IsControlField; if (field.IsControlField == true) { field_line.Content = field.Content; field_line.ExpandState = ExpandState.None; } else { #if NO // 指示符行 IndicatorLine indicator_line = new IndicatorLine(this); indicator_line.Name = ""; indicator_line.Caption = "指示符"; indicator_line.Content = field.Indicator; InsertNewLine(nLineIndex++, indicator_line); #endif field_line.Indicator = field.Indicator; foreach (MarcSubfield subfield in field.ChildNodes) { SubfieldLine subfield_line = new SubfieldLine(this); subfield_line.Name = subfield.Name; subfield_line.Caption = GetCaption(field.Name, subfield.Name, this._includeNumber); subfield_line.Content = subfield.Content; InsertNewLine(nLineIndex++, subfield_line, false); } field_line.ExpandState = ExpandState.Expanded; } } this.Changed = false; ResetLineState(); } finally { this.EnableUpdate(); } }
void DisplayFirstRecord(string strFileName, Encoding encoding) { if (string.IsNullOrEmpty(strFileName) == true) goto ERROR1; if (File.Exists(strFileName) == false) goto ERROR1; if (encoding == null) goto ERROR1; string strMARC = ""; string strError = ""; // return: // -1 出错 // 0 正常 int nRet = LoadFirstRecord(strFileName, encoding, out strMARC, out strError); if (nRet == -1) goto ERROR1; if (this.Mode880 == true && (this.comboBox_marcSyntax.Text == "USMARC" || this.comboBox_marcSyntax.Text == "<自动>")) { if (this.IsOutput == false) { MarcRecord temp = new MarcRecord(strMARC); MarcQuery.ToParallel(temp); strMARC = temp.Text; } } string strHead = @"<head> <style type='text/css'> BODY { FONT-FAMILY: Microsoft YaHei, Verdana, 宋体; FONT-SIZE: 8pt; } TABLE.marc { font-size: 8pt; width: auto; } TABLE.marc TD { vertical-align:text-top; } TABLE.marc TR.header { background-color: #eeeeee; } TABLE.marc TR.datafield { } TABLE.marc TD.fieldname { border: 0px; border-top: 1px; border-style: dotted; border-color: #cccccc; } TABLE.marc TD.fieldname, TABLE.marc TD.indicator, TABLE.marc TR.header TD.content, TABLE.marc SPAN { font-family: Courier New, Tahoma, Arial, Helvetica, sans-serif; font-weight: bold; } TABLE.marc TD.indicator { padding-left: 4px; padding-right: 4px; border: 0px; border-left: 1px; border-right: 1px; border-style: dotted; border-color: #eeeeee; } TABLE.marc SPAN.subfield { margin: 2px; margin-left: 0px; line-height: 140%; border: 1px; border-style: solid; border-color: #cccccc; padding-top: 1px; padding-bottom: 1px; padding-left: 3px; padding-right: 3px; font-weight: bold; color: Blue; background-color: Yellow; } TABLE.marc SPAN.fieldend { margin: 2px; margin-left: 4px; border: 1px; border-style: solid; border-color: #cccccc; padding-top: 1px; padding-bottom: 1px; padding-left: 3px; padding-right: 3px; font-weight: bold; color: White; background-color: #cccccc; } </style> </head>"; string strHtml = "<html>" + strHead + "<body>" + MarcUtil.GetHtmlOfMarc(strMARC, false) + "</body></html>"; AppendHtml(this.webBrowser1, strHtml, true); if (this.IsOutput == false && this.Visible == true) { HideMessageTip(); ShowMessageTip(); } return; ERROR1: ClearHtml(); }
public void menuItem_saveOriginRecordToIso2709_Click(object sender, EventArgs e) { string strError = ""; int nRet = 0; if (this.listView_browse.SelectedIndices.Count == 0) { strError = "尚未选定要保存记录的浏览行"; goto ERROR1; } bool bForceFull = false; if (HasSelectionContainBriefRecords() == true) { DialogResult result = MessageBox.Show(this, "即将保存的记录中有Brief(简要)格式的记录,是否在保存前重新获取为Full(完整)格式的记录?\r\n\r\n(Yes: 是,要完整格式的记录; No: 否,依然保存简明格式的记录; Cancel: 取消,放弃整个保存操作", "AmazonSearchForm", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == System.Windows.Forms.DialogResult.Cancel) return; if (result == System.Windows.Forms.DialogResult.Yes) bForceFull = true; } Encoding preferredEncoding = Encoding.UTF8; #if NO { // 观察要保存的第一条记录的marc syntax int first_index = this.listView_browse.SelectedIndices[0]; ListViewItem first_item = this.listView_browse.Items[first_index]; preferredEncoding = connection.GetRecordsEncoding( this.m_mainForm, first_record.m_strSyntaxOID); } #endif OpenMarcFileDlg dlg = new OpenMarcFileDlg(); GuiUtil.SetControlFont(dlg, this.Font); dlg.IsOutput = true; dlg.GetEncoding -= new GetEncodingEventHandler(dlg_GetEncoding); dlg.GetEncoding += new GetEncodingEventHandler(dlg_GetEncoding); dlg.FileName = m_mainForm.LastIso2709FileName; dlg.CrLf = m_mainForm.LastCrLfIso2709; dlg.RemoveField998Visible = false; //dlg.RemoveField998 = m_mainForm.LastRemoveField998; dlg.EncodingListItems = Global.GetEncodingList(true); dlg.EncodingName = (String.IsNullOrEmpty(m_mainForm.LastEncodingName) == true ? GetEncodingForm.GetEncodingName(preferredEncoding) : m_mainForm.LastEncodingName); dlg.EncodingComment = "注: 原始编码方式为 " + GetEncodingForm.GetEncodingName(preferredEncoding); dlg.MarcSyntax = "<自动>"; // strPreferedMarcSyntax; dlg.EnableMarcSyntax = false; dlg.ShowDialog(this); if (dlg.DialogResult != DialogResult.OK) return; Encoding targetEncoding = null; if (dlg.EncodingName == "MARC-8") { strError = "暂不能使用这个编码方式保存记录。"; goto ERROR1; } nRet = this.m_mainForm.GetEncoding(dlg.EncodingName, out targetEncoding, out strError); if (nRet == -1) { goto ERROR1; } string strLastFileName = m_mainForm.LastIso2709FileName; string strLastEncodingName = m_mainForm.LastEncodingName; bool bExist = File.Exists(dlg.FileName); bool bAppend = false; if (bExist == true) { DialogResult result = MessageBox.Show(this, "文件 '" + dlg.FileName + "' 已存在,是否以追加方式写入记录?\r\n\r\n--------------------\r\n注:(是)追加 (否)覆盖 (取消)放弃", "AmazonSearchForm", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == DialogResult.Yes) bAppend = true; if (result == DialogResult.No) bAppend = false; if (result == DialogResult.Cancel) { strError = "放弃处理..."; goto ERROR1; } } // 检查同一个文件连续存时候的编码方式一致性 if (strLastFileName == dlg.FileName && bAppend == true) { if (strLastEncodingName != "" && strLastEncodingName != dlg.EncodingName) { DialogResult result = MessageBox.Show(this, "文件 '" + dlg.FileName + "' 已在先前已经用 " + strLastEncodingName + " 编码方式存储了记录,现在又以不同的编码方式 " + dlg.EncodingName + " 追加记录,这样会造成同一文件中存在不同编码方式的记录,可能会令它无法被正确读取。\r\n\r\n是否继续? (是)追加 (否)放弃操作", "AmazonSearchForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.No) { strError = "放弃处理..."; goto ERROR1; } } } m_mainForm.LastIso2709FileName = dlg.FileName; m_mainForm.LastCrLfIso2709 = dlg.CrLf; m_mainForm.LastEncodingName = dlg.EncodingName; // m_mainForm.LastRemoveField998 = dlg.RemoveField998; Stream s = null; try { s = File.Open(m_mainForm.LastIso2709FileName, FileMode.OpenOrCreate); if (bAppend == false) s.SetLength(0); else s.Seek(0, SeekOrigin.End); } catch (Exception ex) { strError = "打开或创建文件 " + m_mainForm.LastIso2709FileName + " 失败,原因: " + ex.Message; goto ERROR1; } try { // 首先获得详细记录 if (bForceFull == true) { ReloadFullElementSet(); bool bError = WaitSearchFinish(); } for (int i = 0; i < this.listView_browse.SelectedIndices.Count; i++) { int index = this.listView_browse.SelectedIndices[i]; byte[] baTimestamp = null; string strSavePath = ""; string strOutStyle = ""; LoginInfo logininfo = null; long lVersion = 0; string strXmlFragment = ""; DigitalPlatform.Z3950.Record record = null; Encoding currentEncoding = null; string strMARC = ""; nRet = this.GetOneRecord( "marc", index, // 即将废止 "index:" + index.ToString(), bForceFull == true ? "force_full" : "", // false, out strSavePath, out strMARC, out strXmlFragment, out strOutStyle, out baTimestamp, out lVersion, out record, out currentEncoding, out logininfo, out strError); if (nRet == -1) goto ERROR1; byte[] baTarget = null; string strMarcSyntax = ""; if (record.m_strSyntaxOID == "1.2.840.10003.5.1") strMarcSyntax = "unimarc"; if (record.m_strSyntaxOID == "1.2.840.10003.5.10") strMarcSyntax = "usmarc"; #if NO if (dlg.RemoveField998 == true) { MarcRecord temp = new MarcRecord(strMARC); temp.select("field[@name='998']").detach(); strMARC = temp.Text; } #endif if (dlg.Mode880 == true && strMarcSyntax == "usmarc") { MarcRecord temp = new MarcRecord(strMARC); MarcQuery.To880(temp); strMARC = temp.Text; } // 将MARC机内格式转换为ISO2709格式 // parameters: // strMarcSyntax "unimarc" "usmarc" // strSourceMARC [in]机内格式MARC记录。 // targetEncoding [in]输出ISO2709的编码方式为 UTF8 codepage-936等等 // baResult [out]输出的ISO2709记录。字符集受nCharset参数控制。 // 注意,缓冲区末尾不包含0字符。 nRet = MarcUtil.CvtJineiToISO2709( strMARC, strMarcSyntax, targetEncoding, out baTarget, out strError); if (nRet == -1) goto ERROR1; s.Write(baTarget, 0, baTarget.Length); if (dlg.CrLf == true) { byte[] baCrLf = targetEncoding.GetBytes("\r\n"); s.Write(baCrLf, 0, baCrLf.Length); } } // if (bAppend == true) m_mainForm.MessageText = this.listView_browse.SelectedIndices.Count.ToString() + "条记录成功追加到文件 " + m_mainForm.LastIso2709FileName + " 尾部"; else m_mainForm.MessageText = this.listView_browse.SelectedIndices.Count.ToString() + "条记录成功保存到新文件 " + m_mainForm.LastIso2709FileName + " 尾部"; } catch (Exception ex) { strError = "写入文件 " + m_mainForm.LastIso2709FileName + " 失败,原因: " + ex.Message; goto ERROR1; } finally { s.Close(); } return; ERROR1: MessageBox.Show(this, strError); }
void DisplayFirstRecord(string strFileName, Encoding encoding) { if (string.IsNullOrEmpty(strFileName) == true) { goto ERROR1; } if (File.Exists(strFileName) == false) { goto ERROR1; } if (encoding == null) { goto ERROR1; } string strMARC = ""; string strError = ""; // return: // -1 出错 // 0 正常 int nRet = LoadFirstRecord(strFileName, encoding, out strMARC, out strError); if (nRet == -1) { goto ERROR1; } if (this.Mode880 == true && (this.comboBox_marcSyntax.Text == "USMARC" || this.comboBox_marcSyntax.Text == "<自动>")) { if (this.IsOutput == false) { MarcRecord temp = new MarcRecord(strMARC); MarcQuery.ToParallel(temp); strMARC = temp.Text; } } string strHead = @"<head> <style type='text/css'> BODY { FONT-FAMILY: Microsoft YaHei, Verdana, 宋体; FONT-SIZE: 8pt; } TABLE.marc { font-size: 8pt; width: auto; } TABLE.marc TD { vertical-align:text-top; } TABLE.marc TR.header { background-color: #eeeeee; } TABLE.marc TR.datafield { } TABLE.marc TD.fieldname { border: 0px; border-top: 1px; border-style: dotted; border-color: #cccccc; } TABLE.marc TD.fieldname, TABLE.marc TD.indicator, TABLE.marc TR.header TD.content, TABLE.marc SPAN { font-family: Courier New, Tahoma, Arial, Helvetica, sans-serif; font-weight: bold; } TABLE.marc TD.indicator { padding-left: 4px; padding-right: 4px; border: 0px; border-left: 1px; border-right: 1px; border-style: dotted; border-color: #eeeeee; } TABLE.marc SPAN.subfield { margin: 2px; margin-left: 0px; line-height: 140%; border: 1px; border-style: solid; border-color: #cccccc; padding-top: 1px; padding-bottom: 1px; padding-left: 3px; padding-right: 3px; font-weight: bold; color: Blue; background-color: Yellow; } TABLE.marc SPAN.fieldend { margin: 2px; margin-left: 4px; border: 1px; border-style: solid; border-color: #cccccc; padding-top: 1px; padding-bottom: 1px; padding-left: 3px; padding-right: 3px; font-weight: bold; color: White; background-color: #cccccc; } </style> </head>"; string strHtml = "<html>" + strHead + "<body>" + MarcUtil.GetHtmlOfMarc(strMARC, false) + "</body></html>"; AppendHtml(this.webBrowser1, strHtml, true); if (this.IsOutput == false && this.Visible == true) { HideMessageTip(); ShowMessageTip(); } return; ERROR1: ClearHtml(); }
int ExportTo856SearchForm(out string strError) { strError = ""; int nRet = 0; if (this.listView_records.SelectedItems.Count == 0) { strError = "尚未选定要导出的事项"; return -1; } Marc856SearchForm form = new Marc856SearchForm(); form.MdiParent = this.MainForm; form.MainForm = this.MainForm; form.Show(); this.EnableControls(false); LibraryChannel channel = this.GetChannel(); stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在导出到 MARC 文件 ..."); stop.BeginLoop(); try { List<ListViewItem> items = new List<ListViewItem>(); foreach (ListViewItem item in this.listView_records.SelectedItems) { if (string.IsNullOrEmpty(item.Text) == true) continue; items.Add(item); } ListViewBiblioLoader loader = new ListViewBiblioLoader(channel, // this.Channel, stop, items, this.m_biblioTable); loader.Prompt -= new MessagePromptEventHandler(loader_Prompt); loader.Prompt += new MessagePromptEventHandler(loader_Prompt); List<ListViewItem> new_items = new List<ListViewItem>(); int i = 0; foreach (LoaderItem item in loader) { Application.DoEvents(); // 出让界面控制权 if (stop != null && stop.State != 0) { strError = "用户中断"; return -1; } string strBiblioSummary = ListViewUtil.GetItemText(item.ListViewItem, 1); BiblioInfo info = item.BiblioInfo; string strXml = ""; { if (string.IsNullOrEmpty(info.NewXml) == false) strXml = info.NewXml; else strXml = info.OldXml; } string strMARC = ""; string strMarcSyntax = ""; // 将XML格式转换为MARC格式 // 自动从数据记录中获得MARC语法 nRet = MarcUtil.Xml2Marc(strXml, true, null, out strMarcSyntax, out strMARC, out strError); if (nRet == -1) { strError = "XML转换到MARC记录时出错: " + strError; return -1; } MarcRecord record = new MarcRecord(strMARC); MarcNodeList fields = record.select("field[@name='856']"); if (fields.count == 0) goto CONTINUE; int index = 0; foreach (MarcField field in fields) { ListViewItem new_item = form.AddLine(info.RecPath, info, field, index); new_items.Add(new_item); index++; } CONTINUE: stop.SetProgressValue(++i); } nRet = form.FillBiblioSummaryColumn( channel, new_items, 0, true, true, out strError); if (nRet == -1) return -1; return 0; } catch (Exception ex) { strError = "导出 856 字段的过程出现异常: " + ExceptionUtil.GetAutoText(ex); return -1; } finally { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.HideProgress(); this.ReturnChannel(channel); this.EnableControls(true); } }
// 获得 MARC 记录的 HTML 格式字符串 public static string GetHtmlOfMarc(string strMARC, string strFragmentXml, string strCoverImageFragment, bool bSubfieldReturn) { StringBuilder strResult = new StringBuilder("\r\n<table class='marc'>", 4096); MarcRecord record = new MarcRecord(strMARC); // strResult.Append("\r\n<tr class='header'><td class='fieldname'></td>" + "<td class='indicator'></td>" + "<td class='content'>" + record.Header.ToString() + "</td></tr>"); MarcNodeList fields = record.select("field"); int i = 0; foreach (MarcField field in fields) { string strField = field.Content; string strLineClass = "datafield"; string strFieldName = field.Name; string strIndicatior = field.Indicator; string strContent = ""; if (field.IsControlField) { strLineClass = "controlfield"; strField = strField.Replace(' ', '_'); } strIndicatior = strIndicatior.Replace(' ', '_'); #if NO if (i != 0) { // 取字段名 if (strField.Length < 3) { strFieldName = strField; strField = ""; } else { strFieldName = strField.Substring(0, 3); strField = strField.Substring(3); } // 取指示符 if (IsControlFieldName(strFieldName) == true) { strLineClass = "controlfield"; strField = strField.Replace(' ', '_'); } else { if (strField.Length < 2) { strIndicatior = strField; strField = ""; } else { strIndicatior = strField.Substring(0, 2); strField = strField.Substring(2); } strIndicatior = strIndicatior.Replace(' ', '_'); strLineClass = "datafield"; // 1XX字段有定长内容 if (strFieldName.Length >= 1 && strFieldName[0] == '1') { strField = strField.Replace(' ', '_'); strLineClass += " fixedlengthsubfield"; } } } else { strLineClass = "header"; strField = strField.Replace(' ', '_'); } #endif strContent = GetHtmlFieldContent(strField, bSubfieldReturn); // strResult.Append("\r\n<tr class='" + strLineClass + "'><td class='fieldname'>" + strFieldName + "</td>" + "<td class='indicator'>" + strIndicatior + "</td>" + "<td class='content'>" + strContent + "</td></tr>"); if (i == 0) { strResult.Append(GetImageHtml(strCoverImageFragment)); } i++; } if (string.IsNullOrEmpty(strFragmentXml) == false) { strResult.Append(GetFragmentHtml(strFragmentXml)); } strResult.Append("\r\n</table>"); return(strResult.ToString()); }
/// <summary> /// 创建一个新的 MarcRecord 节点对象,从当前对象复制出全部内容和下级节点 /// </summary> /// <returns>新的节点对象</returns> public override MarcNode clone() { MarcNode new_node = new MarcRecord(); new_node.Text = this.Text; new_node.Parent = null; // 尚未和任何对象连接 return new_node; }
// 2015/10/10 // 保存到 MARC 文件 void menu_saveToMarcFile_Click(object sender, EventArgs e) { string strError = ""; int nRet = 0; if (this.listView_records.SelectedItems.Count == 0) { strError = "尚未选定要导出的事项"; goto ERROR1; } Encoding preferredEncoding = this.CurrentEncoding; { // 观察要保存的第一条记录的marc syntax } OpenMarcFileDlg dlg = new OpenMarcFileDlg(); MainForm.SetControlFont(dlg, this.Font); dlg.IsOutput = true; dlg.AddG01Visible = false; dlg.RuleVisible = true; dlg.Rule = this.LastCatalogingRule; dlg.FileName = this.LastIso2709FileName; dlg.CrLf = this.LastCrLfIso2709; dlg.RemoveField998 = this.LastRemoveField998; dlg.EncodingListItems = Global.GetEncodingList(false); dlg.EncodingName = (String.IsNullOrEmpty(this.LastEncodingName) == true ? Global.GetEncodingName(preferredEncoding) : this.LastEncodingName); dlg.EncodingComment = "注: 原始编码方式为 " + Global.GetEncodingName(preferredEncoding); dlg.MarcSyntax = "<自动>"; // strPreferedMarcSyntax; dlg.EnableMarcSyntax = false; dlg.ShowDialog(this); if (dlg.DialogResult != DialogResult.OK) return; string strCatalogingRule = dlg.Rule; if (strCatalogingRule == "<无限制>") strCatalogingRule = null; Encoding targetEncoding = null; nRet = Global.GetEncoding(dlg.EncodingName, out targetEncoding, out strError); if (nRet == -1) { goto ERROR1; } string strLastFileName = this.LastIso2709FileName; string strLastEncodingName = this.LastEncodingName; bool bExist = File.Exists(dlg.FileName); bool bAppend = false; if (bExist == true) { DialogResult result = MessageBox.Show(this, "文件 '" + dlg.FileName + "' 已存在,是否以追加方式写入记录?\r\n\r\n--------------------\r\n注:(是)追加 (否)覆盖 (取消)放弃", "BiblioSearchForm", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == DialogResult.Yes) bAppend = true; if (result == DialogResult.No) bAppend = false; if (result == DialogResult.Cancel) { strError = "放弃处理..."; goto ERROR1; } } // 检查同一个文件连续存时候的编码方式一致性 if (strLastFileName == dlg.FileName && bAppend == true) { if (strLastEncodingName != "" && strLastEncodingName != dlg.EncodingName) { DialogResult result = MessageBox.Show(this, "文件 '" + dlg.FileName + "' 已在先前已经用 " + strLastEncodingName + " 编码方式存储了记录,现在又以不同的编码方式 " + dlg.EncodingName + " 追加记录,这样会造成同一文件中存在不同编码方式的记录,可能会令它无法被正确读取。\r\n\r\n是否继续? (是)追加 (否)放弃操作", "BiblioSearchForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.No) { strError = "放弃处理..."; goto ERROR1; } } } this.LastIso2709FileName = dlg.FileName; this.LastCrLfIso2709 = dlg.CrLf; this.LastEncodingName = dlg.EncodingName; this.LastCatalogingRule = dlg.Rule; this.LastRemoveField998 = dlg.RemoveField998; Stream s = null; try { s = File.Open(this.LastIso2709FileName, FileMode.OpenOrCreate); if (bAppend == false) s.SetLength(0); else s.Seek(0, SeekOrigin.End); } catch (Exception ex) { strError = "打开或创建文件 " + this.LastIso2709FileName + " 失败,原因: " + ex.Message; goto ERROR1; } LibraryChannel channel = this.GetChannel(); this.EnableControls(false); stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在导出到 MARC 文件 ..."); stop.BeginLoop(); try { stop.SetProgressRange(0, this.listView_records.SelectedItems.Count); List<ListViewItem> items = new List<ListViewItem>(); foreach (ListViewItem item in this.listView_records.SelectedItems) { if (string.IsNullOrEmpty(item.Text) == true) continue; items.Add(item); } ListViewBiblioLoader loader = new ListViewBiblioLoader(channel, // this.Channel, stop, items, this.m_biblioTable); loader.Prompt -= new MessagePromptEventHandler(loader_Prompt); loader.Prompt += new MessagePromptEventHandler(loader_Prompt); int i = 0; foreach (LoaderItem item in loader) { Application.DoEvents(); // 出让界面控制权 if (stop != null && stop.State != 0) { strError = "用户中断"; goto ERROR1; } #if NO string[] results = null; byte[] baTimestamp = null; stop.SetMessage("正在获取书目记录 " + strRecPath); long lRet = Channel.GetBiblioInfos( stop, strRecPath, "", new string[] { "xml" }, // formats out results, out baTimestamp, out strError); if (lRet == 0) goto ERROR1; if (lRet == -1) goto ERROR1; if (results == null || results.Length == 0) { strError = "results error"; goto ERROR1; } string strXml = results[0]; #endif BiblioInfo info = item.BiblioInfo; string strXml = ""; { if (string.IsNullOrEmpty(info.NewXml) == false) strXml = info.NewXml; else strXml = info.OldXml; } string strMARC = ""; string strMarcSyntax = ""; // 将XML格式转换为MARC格式 // 自动从数据记录中获得MARC语法 nRet = MarcUtil.Xml2Marc(strXml, true, null, out strMarcSyntax, out strMARC, out strError); if (nRet == -1) { strError = "XML转换到MARC记录时出错: " + strError; goto ERROR1; } byte[] baTarget = null; Debug.Assert(strMarcSyntax != "", ""); // 按照编目规则过滤 // 获得一个特定风格的 MARC 记录 // parameters: // strStyle 要匹配的style值。如果为null,表示任何$*值都匹配,实际上效果是去除$*并返回全部字段内容 // return: // 0 没有实质性修改 // 1 有实质性修改 nRet = MarcUtil.GetMappedRecord(ref strMARC, strCatalogingRule); if (dlg.RemoveField998 == true) { MarcRecord record = new MarcRecord(strMARC); record.select("field[@name='998']").detach(); strMARC = record.Text; } if (dlg.Mode880 == true && strMarcSyntax == "usmarc") { MarcRecord record = new MarcRecord(strMARC); MarcQuery.To880(record); strMARC = record.Text; } // 将MARC机内格式转换为ISO2709格式 // parameters: // strSourceMARC [in]机内格式MARC记录。 // strMarcSyntax [in]为"unimarc"或"usmarc" // targetEncoding [in]输出ISO2709的编码方式。为UTF8、codepage-936等等 // baResult [out]输出的ISO2709记录。编码方式受targetEncoding参数控制。注意,缓冲区末尾不包含0字符。 // return: // -1 出错 // 0 成功 nRet = MarcUtil.CvtJineiToISO2709( strMARC, strMarcSyntax, targetEncoding, out baTarget, out strError); if (nRet == -1) goto ERROR1; s.Write(baTarget, 0, baTarget.Length); if (dlg.CrLf == true) { byte[] baCrLf = targetEncoding.GetBytes("\r\n"); s.Write(baCrLf, 0, baCrLf.Length); } stop.SetProgressValue(++i); } } catch (Exception ex) { strError = "写入文件 " + this.LastIso2709FileName + " 失败,原因: " + ex.Message; goto ERROR1; } finally { s.Close(); stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.HideProgress(); this.ReturnChannel(channel); this.EnableControls(true); } // if (bAppend == true) MainForm.StatusBarMessage = this.listView_records.SelectedItems.Count.ToString() + "条记录成功追加到文件 " + this.LastIso2709FileName + " 尾部"; else MainForm.StatusBarMessage = this.listView_records.SelectedItems.Count.ToString() + "条记录成功保存到新文件 " + this.LastIso2709FileName; return; ERROR1: MessageBox.Show(this, strError); }
private void ToolStripMenuItem_removeCoverImage_Click(object sender, EventArgs e) { bool bChanged = false; MarcRecord record = new MarcRecord(this.GetMarc()); MarcNodeList subfields = record.select("field[@name='856']/subfield[@name='x']"); foreach (MarcSubfield subfield in subfields) { string x = subfield.Content; if (string.IsNullOrEmpty(x) == true) continue; Hashtable table = StringUtil.ParseParameters(x, ';', ':'); string strType = (string)table["type"]; if (string.IsNullOrEmpty(strType) == true) continue; if (StringUtil.HasHead(strType, "FrontCover") == true) { string u = subfield.Parent.select("subfield[@name='u']").FirstContent; subfield.Parent.detach(); bChanged = true; DeleteImageObject(GetImageID(u)); } } if (bChanged == true) this.SetMarc(record.Text); else MessageBox.Show(this, "没有发现封面图像的 856 字段"); }
public static string GetIsbnImageHtmlFragment(string strMARC, string strMarcSyntax) { List<string> isbns = new List<string>(); MarcRecord record = new MarcRecord(strMARC); if (strMarcSyntax == "usmarc") { } else { // unimarc MarcNodeList subfields = record.select("field[@name='010']/subfield[@name='a']"); foreach(MarcSubfield subfield in subfields) { if (string.IsNullOrEmpty(subfield.Content) == false) isbns.Add(IsbnSplitter.GetISBnBarcode(subfield.Content)); // 如果必要,转换为 13 位 } } StringBuilder text = new StringBuilder(); foreach(string isbn in isbns) { Hashtable table = new Hashtable(); table["code"] = isbn; table["type"] = "ean_13"; table["width"] = "300"; table["height"] = "80"; string path = StringUtil.BuildParameterString(table, ',','=', "url"); text.Append("<img src='barcode:" + path + "'></img><br/>"); } return text.ToString(); }