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); }
// 组合构造若干个856字段内容 static string BuildLinks(MarcNodeList fields) { StringBuilder text = new StringBuilder(4096); int i = 0; foreach (MarcNode field in fields) { MarcNodeList nodes = field.select("subfield"); if (nodes.count > 0) { string u = ""; MarcNodeList single = nodes.select("subfield[@name='u']"); if (single.count > 0) { u = single[0].Content; } string z = ""; single = nodes.select("subfield[@name='z']"); if (single.count > 0) { z = single[0].Content; } string t3 = ""; single = nodes.select("subfield[@name='3']"); if (single.count > 0) { t3 = single[0].Content; } if (i > 0) { text.Append(CRLF); } StringBuilder temp = new StringBuilder(4096); if (string.IsNullOrEmpty(t3) == false) { temp.Append(t3 + ": <|"); } temp.Append("url:" + u); temp.Append(" text:" + u); if (string.IsNullOrEmpty(z) == false) { temp.Append("|> " + z); } text.Append(temp.ToString().Trim()); i++; } } return(text.ToString().Trim()); }
// parameters: // subfieldList 字符串数组。每个单元格式如下: "a; " 第一字符表示子字段名,后面若干字符表示要插入的前置符号。 static string BuildContent(MarcRecord record, string fieldName, string[] subfieldList, bool trimStart) { List <char> chars = new List <char>() { ' ' }; // 用于 TrimStart 的字符 Hashtable prefix_table = new Hashtable(); // name -> prefix StringBuilder xpath = new StringBuilder(); xpath.Append("field[@name='200']/subfield["); int i = 0; foreach (string s in subfieldList) { string name = s.Substring(0, 1); string prefix = s.Substring(1); prefix_table[name] = prefix; string strChar = prefix.Trim(); if (string.IsNullOrEmpty(strChar) == false) { chars.Add(strChar[0]); } if (i > 0) { xpath.Append(" or "); } xpath.Append("@name='" + name + "'"); i++; } xpath.Append("]"); MarcNodeList subfields = record.select(xpath.ToString()); StringBuilder text = new StringBuilder(); foreach (MarcSubfield subfield in subfields) { string prefix = (string)prefix_table[subfield.Name]; if (string.IsNullOrEmpty(prefix) == false) { text.Append(prefix + subfield.Content); } else { text.Append(" " + subfield.Content); } } if (trimStart) { return(text.ToString().TrimStart(chars.ToArray())); } return(text.ToString()); }
// 组合构造若干个主题字段内容 static string BuildSubjects(MarcNodeList fields) { StringBuilder text = new StringBuilder(4096); int i = 0; foreach (MarcNode field in fields) { MarcNodeList nodes = field.select("subfield"); if (nodes.count > 0) { if (i > 0) { text.Append(CRLF); } bool bPrevContent = false; // 前一个子字段是除了 x y z 以外的子字段 StringBuilder temp = new StringBuilder(4096); foreach (MarcNode subfield in nodes) { if (subfield.Name == "6") { continue; } if (subfield.Name == "2") { continue; // 不使用 $2 } if (subfield.Name == "x" || subfield.Name == "y" || subfield.Name == "z" || subfield.Name == "v") { temp.Append("--"); temp.Append(subfield.Content); bPrevContent = false; } else { if (bPrevContent == true) { temp.Append(" "); } temp.Append(subfield.Content); bPrevContent = true; } } text.Append(temp.ToString().Trim()); i++; } } return(text.ToString().Trim()); }
// 直接串联每个子字段的内容 static string ConcatSubfields(MarcNodeList nodes) { StringBuilder text = new StringBuilder(4096); foreach (MarcNode node in nodes) { if (node.Name == "6") { continue; } text.Append(node.Content + " "); } return(text.ToString().Trim()); }
// 组合构造若干个普通字段内容 // parameters: // strSubfieldNameList 筛选的子字段名列表。如果为 null,表示不筛选 static string BuildFields(MarcNodeList fields, string strSubfieldNameList = null) { StringBuilder text = new StringBuilder(4096); int i = 0; foreach (MarcNode field in fields) { MarcNodeList nodes = field.select("subfield"); if (nodes.count > 0) { StringBuilder temp = new StringBuilder(4096); foreach (MarcNode subfield in nodes) { if (subfield.Name == "6") { continue; } if (strSubfieldNameList != null) { if (strSubfieldNameList.IndexOf(subfield.Name) == -1) { continue; } } temp.Append(subfield.Content + " "); } if (temp.Length > 0) { if (i > 0) { text.Append(CRLF); } text.Append(temp.ToString().Trim()); i++; } } } return(text.ToString().Trim()); }
void SetSubfield(string strName, string strValue) { Debug.Assert(strName.Length == 1, ""); MarcField field = _record.ChildNodes[0] as MarcField; MarcNodeList subfields = field.select("subfield[@name='" + strName + "']"); if (subfields.count == 0) { if (string.IsNullOrEmpty(strValue) == true) { return; } // 以前不存在这个子字段,只能追加 field.add(new MarcSubfield(strName, strValue)); return; } // 原位置修改 subfields[0].Content = strValue; }
// 组合构造若干个普通字段内容 // parameters: // strSubfieldNameList 筛选的子字段名列表。如果为 null,表示不筛选 static string BuildFields(MarcNodeList fields, string strSubfieldNameList = null) { StringBuilder text = new StringBuilder(4096); int i = 0; foreach (MarcNode field in fields) { MarcNodeList nodes = field.select("subfield"); if (nodes.count > 0) { StringBuilder temp = new StringBuilder(4096); foreach (MarcNode subfield in nodes) { if (strSubfieldNameList != null) { if (strSubfieldNameList.IndexOf(subfield.Name) == -1) continue; } temp.Append(subfield.Content + " "); } if (temp.Length > 0) { if (i > 0) text.Append("|"); text.Append(temp.ToString().Trim()); i++; } } } return text.ToString().Trim(); }
// 组合构造若干个主题字段内容 static string BuildSubjects(MarcNodeList fields) { StringBuilder text = new StringBuilder(4096); int i = 0; foreach (MarcNode field in fields) { MarcNodeList nodes = field.select("subfield"); if (nodes.count > 0) { if (i > 0) text.Append("|"); bool bPrevContent = false; // 前一个子字段是除了 x y z 以外的子字段 StringBuilder temp = new StringBuilder(4096); foreach (MarcNode subfield in nodes) { if (subfield.Name == "2") continue; // 不使用 $2 if (subfield.Name == "x" || subfield.Name == "y" || subfield.Name == "z" || subfield.Name == "v") { temp.Append("--"); temp.Append(subfield.Content); bPrevContent = false; } else { if (bPrevContent == true) temp.Append(" "); temp.Append(subfield.Content); bPrevContent = true; } } text.Append(temp.ToString().Trim()); i++; } } return text.ToString().Trim(); }
// 构建集合对象 // 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); }
// 直接串联每个子字段的内容 static string ConcatSubfields(MarcNodeList nodes) { StringBuilder text = new StringBuilder(4096); foreach (MarcNode node in nodes) { text.Append(node.Content + " "); } return text.ToString().Trim(); }
// 追加 /// <summary> /// 在当前集合末尾追加若干节点元素 /// </summary> /// <param name="list">要追加的若干节点元素</param> public new void add(MarcNodeList list) { base.add(list); Debug.Assert(owner != null, ""); foreach (MarcNode node in list) { node.Parent = owner; } }
// 把strText构造的新对象插入到this的下级开头位置。返回this /// <summary> /// 用指定的字符串构造出新节点,插入到当前节点的子节点开头 /// </summary> /// <param name="strText">用于构造新节点的字符串</param> /// <returns>当前节点</returns> public MarcNode prepend(string strText) { MarcNodeList targets = new MarcNodeList(this); targets.prepend(strText); return this; }
// 根据机内格式的片断字符串,构造若干MarcSubfield对象 // parameters: // parent 要赋给新创建的MarcSubfield对象的Parent值 // strLeadingString [out] 第一个 31 字符以前的文本部分 /// <summary> /// 根据机内格式 MARC 字符串,创建若干 MarcSubfield 对象 /// </summary> /// <param name="strText">MARC 机内格式字符串</param> /// <param name="strLeadingString">返回前导部分字符串。也就是 strText 中第一个子字段符号以前的部分</param> /// <returns>新创建的 MarcSubfield 对象集合</returns> public static MarcNodeList createSubfields( string strText, out string strLeadingString) { strLeadingString = ""; MarcNodeList results = new MarcNodeList(); List<string> segments = new List<string>(); StringBuilder prefix = new StringBuilder(); // 第一个 31 出现以前的一段文字 StringBuilder segment = new StringBuilder(); // 正在追加的内容段落 for (int i = 0; i < strText.Length; i++) { char ch = strText[i]; if (ch == 31) { // 如果先前有累积的,推走 if (segment.Length > 0) { segments.Add(segment.ToString()); segment.Clear(); } segment.Append(ch); } else { if (segment.Length > 0 || segments.Count > 0) segment.Append(ch); else prefix.Append(ch);// 第一个子字段符号以前的内容放在这里 } } if (segment.Length > 0) { segments.Add(segment.ToString()); segment.Clear(); } if (prefix.Length > 0) strLeadingString = prefix.ToString(); foreach (string s in segments) { MarcSubfield subfield = new MarcSubfield(); if (s.Length < 2) subfield.Text = MarcQuery.SUBFLD + "?"; // TODO: 或者可以忽略? else subfield.Text = s; results.add(subfield); // Debug.Assert(subfield.Parent == parent, ""); } return results; }
// 创建 OPAC 详细页面中的对象资源显示局部 HTML。这是一个 <table> 片段 // 前导语 $3 // 链接文字 $y $f // URL $u // 格式类型 $q // 对象ID $8 // 对象尺寸 $s // 公开注释 $z public static string BuildObjectHtmlTable(string strMARC, string strRecPath, BuildObjectHtmlTableStyle style = BuildObjectHtmlTableStyle.HttpUrlHitCount) { // Debug.Assert(false, ""); MarcRecord record = new MarcRecord(strMARC); MarcNodeList fields = record.select("field[@name='856']"); if (fields.count == 0) { return(""); } StringBuilder text = new StringBuilder(); text.Append("<table class='object_table'>"); text.Append("<tr class='column_title'>"); text.Append("<td class='type' style='word-break:keep-all;'>名称</td>"); text.Append("<td class='hitcount'></td>"); text.Append("<td class='link' style='word-break:keep-all;'>链接</td>"); text.Append("<td class='mime' style='word-break:keep-all;'>媒体类型</td>"); text.Append("<td class='size' style='word-break:keep-all;'>尺寸</td>"); text.Append("<td class='bytes' style='word-break:keep-all;'>字节数</td>"); text.Append("</tr>"); int nCount = 0; foreach (MarcField field in fields) { string x = field.select("subfield[@name='x']").FirstContent; Hashtable table = StringUtil.ParseParameters(x, ';', ':'); string strType = (string)table["type"]; if (string.IsNullOrEmpty(strType) == false && (style & BuildObjectHtmlTableStyle.FrontCover) == 0 && (strType == "FrontCover" || strType.StartsWith("FrontCover.") == true)) { continue; } string strSize = (string)table["size"]; string s_q = field.select("subfield[@name='q']").FirstContent; // 注意, FirstContent 可能会返回 null string u = field.select("subfield[@name='u']").FirstContent; string strUri = MakeObjectUrl(strRecPath, u); string strSaveAs = ""; if (string.IsNullOrEmpty(s_q) == true || StringUtil.MatchMIME(s_q, "text") == true || StringUtil.MatchMIME(s_q, "image") == true) { } else { strSaveAs = "&saveas=true"; } string strHitCountImage = ""; string strObjectUrl = strUri; if (StringUtil.IsHttpUrl(strUri) == false) { // 内部对象 strObjectUrl = "./getobject.aspx?uri=" + HttpUtility.UrlEncode(strUri) + strSaveAs; strHitCountImage = "<img src='" + strObjectUrl + "&style=hitcount' alt='hitcount'></img>"; } else { // http: 或 https: 的情形,即外部 URL if ((style & BuildObjectHtmlTableStyle.HttpUrlHitCount) != 0) { strObjectUrl = "./getobject.aspx?uri=" + HttpUtility.UrlEncode(strUri) + strSaveAs + "&biblioRecPath=" + HttpUtility.UrlEncode(strRecPath); strHitCountImage = "<img src='" + strObjectUrl + "&style=hitcount&biblioRecPath=" + HttpUtility.UrlEncode(strRecPath) + "' alt='hitcount'></img>"; } } string y = field.select("subfield[@name='y']").FirstContent; string f = field.select("subfield[@name='f']").FirstContent; string urlLabel = ""; if (string.IsNullOrEmpty(y) == false) { urlLabel = y; } else { urlLabel = f; } if (string.IsNullOrEmpty(urlLabel) == true) { urlLabel = strType; } // 2015/11/26 string s_z = field.select("subfield[@name='z']").FirstContent; if (string.IsNullOrEmpty(urlLabel) == true && string.IsNullOrEmpty(s_z) == false) { urlLabel = s_z; s_z = ""; } if (string.IsNullOrEmpty(urlLabel) == true) { urlLabel = strObjectUrl; } string urlTemp = ""; if (String.IsNullOrEmpty(strObjectUrl) == false) { urlTemp += "<a href='" + strObjectUrl + "'>"; urlTemp += urlLabel; urlTemp += "</a>"; } else { urlTemp = urlLabel; } string s_3 = field.select("subfield[@name='3']").FirstContent; string s_s = field.select("subfield[@name='s']").FirstContent; text.Append("<tr class='content'>"); text.Append("<td class='type'>" + HttpUtility.HtmlEncode(s_3 + " " + strType) + "</td>"); text.Append("<td class='hitcount' style='text-align: right;'>" + strHitCountImage + "</td>"); text.Append("<td class='link' style='word-break:break-all;'>" + urlTemp + "</td>"); text.Append("<td class='mime'>" + HttpUtility.HtmlEncode(s_q) + "</td>"); text.Append("<td class='size'>" + HttpUtility.HtmlEncode(strSize) + "</td>"); text.Append("<td class='bytes'>" + HttpUtility.HtmlEncode(s_s) + "</td>"); text.Append("</tr>"); if (string.IsNullOrEmpty(s_z) == false) { text.Append("<tr class='comment'>"); text.Append("<td colspan='6'>" + HttpUtility.HtmlEncode(s_z) + "</td>"); text.Append("</tr>"); } nCount++; } if (nCount == 0) { return(""); } text.Append("</table>"); return(text.ToString()); }
// 在目标集合中每个元素的DOM位置后面(同级)插入源集合内的元素 // 注1: 如果目标集合为空,则本函数不作任何操作。这样可以防止元素被摘除但没有插入到任何位置 // 注2:将 源 插入到 目标 元素的DOM位置后面。如果源头元素在DOM树上,则先摘除它然后插入到新位置,不是复制。 // 注3: 如果目标集合中包含多于一个元素,则分为多轮插入。第二轮以后插入的对象,是源集合中的对象复制出来的新对象 /// <summary> /// 在目标集合中每个元素的 DOM 位置后面(同级)插入源集合内的元素 /// </summary> /// <param name="source_nodes">源集合</param> /// <param name="target_nodes">目标集合</param> public static void insertAfter( MarcNodeList source_nodes, MarcNodeList target_nodes) { if (source_nodes.count == 0) return; if (target_nodes.count == 0) return; // record.SelectNodes("field[@name='690']")[0].ChildNodes.after(SUBFLD + "x第一个" + SUBFLD + "z第二个"); if (target_nodes is ChildNodeList) { // 数组框架复制,但其中的元素不是复制而是引用 MarcNodeList temp = new MarcNodeList(); temp.add(target_nodes); target_nodes = temp; } // 先(从原有DOM位置)摘除当前集合内的全部元素 source_nodes.detach(); int i = 0; foreach (MarcNode target_node in target_nodes) { MarcNode target = target_node; foreach (MarcNode source_node in source_nodes) { MarcNode source = source_node; if (i > 0) // 第一轮以后,源对象每个都要复制后插入目标位置 { source = source.clone(); target.after(source); } else target.after(source); target = source; // 插入后参考位置要顺延 } i++; } }
/// <summary> /// 在目标集合中每个元素的 DOM 位置前面(同级)插入源集合内的元素 /// </summary> /// <param name="source_nodes">源集合</param> /// <param name="target_nodes">目标集合</param> public static void insertBefore( MarcNodeList source_nodes, MarcNodeList target_nodes) { if (source_nodes.count == 0) return; if (target_nodes.count == 0) return; if (target_nodes is ChildNodeList) { // 数组框架复制,但其中的元素不是复制而是引用 MarcNodeList temp = new MarcNodeList(); temp.add(target_nodes); target_nodes = temp; } // 先(从原有DOM位置)摘除当前集合内的全部元素 source_nodes.detach(); int i = 0; foreach (MarcNode target_node in target_nodes) { MarcNode target = target_node; foreach (MarcNode source_node in source_nodes) { MarcNode source = source_node; if (i > 0) // 第一轮以后,源对象每个都要复制后插入目标位置 { source = source.clone(); target.before(source); } else target.before(source); target = source; // 插入后参考位置要顺延 } i++; } }
/// <summary> /// 根据机内格式 MARC 字符串,创建若干 MarcInnerField 对象 /// </summary> /// <param name="strText">MARC 机内格式字符串。代表内嵌字段的那个局部。例如 "$1200 $axxxx$fxxxx$1225 $axxxx"</param> /// <param name="strLeadingString">返回引导字符串。也就是第一个子字段符号前的部分</param> /// <returns>新创建的 MarcInnerField 对象数组</returns> public static MarcNodeList createInnerFields( string strText, out string strLeadingString) { strLeadingString = ""; MarcNodeList results = new MarcNodeList(); strText = strText.Replace(SUBFLD + "1", FLDEND); List<string> segments = new List<string>(); StringBuilder prefix = new StringBuilder(); // 第一个 30 出现以前的一段文字 StringBuilder segment = new StringBuilder(); // 正在追加的内容段落 for (int i = 0; i < strText.Length; i++) { char ch = strText[i]; if (ch == FLDEND[0]) { // 如果先前有累积的,推走 if (segment.Length > 0) { segments.Add(segment.ToString()); segment.Clear(); } //segment.Append(ch); segment.Append(SUBFLD + "1"); } else { if (segment.Length > 0 || segments.Count > 0) segment.Append(ch); else prefix.Append(ch);// 第一个子字段符号以前的内容放在这里 } } if (segment.Length > 0) { segments.Add(segment.ToString()); segment.Clear(); } if (prefix.Length > 0) strLeadingString = prefix.ToString(); foreach (string s in segments) { string strSegment = s; MarcInnerField field = null; field = new MarcInnerField(); // 如果长度不足 5 字符,补齐 // 5 字符是 $1200 的意思 if (strSegment.Length < 5) strSegment = strSegment.PadRight(5, '?'); field.Text = strSegment; results.add(field); // Debug.Assert(field.Parent == parent, ""); } return results; }
public static int ScriptMarc21( 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); } string strImageUrl = ScriptUtil.GetCoverImageUrl(strMARC, "LargeImage"); // LargeImage if (string.IsNullOrEmpty(strImageUrl) == false) { results.Add(new NameValueLine("_coverImage", strImageUrl)); } // 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), "author")); } } // 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), "title")); } #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), "publisher")); // 附加的空格便于在 HTML 中自然折行 } } // 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), "isbn")); } // 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), "issn")); } // 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"))); } fields = record.select("field[@name='856' or @name='859']"); if (fields.count > 0) { string strXml = ScriptUtil.BuildObjectXmlTable(strMARC); if (string.IsNullOrEmpty(strXml) == false) { var line = new NameValueLine("Digital Resource", "", "object"); line.Xml = strXml; results.Add(line); } } return(0); }
// 在目标集合中每个元素的DOM位置 下级开头 插入源集合内的元素 /// <summary> /// 在目标集合中每个元素的 DOM 位置下级开头插入源集合内的元素 /// </summary> /// <param name="source_nodes">源集合</param> /// <param name="target_nodes">目标集合</param> public static void prepend( MarcNodeList source_nodes, MarcNodeList target_nodes) { if (source_nodes.count == 0) return; if (target_nodes.count == 0) return; // 防范目标集合被动态修改后发生foreach报错 if (target_nodes is ChildNodeList) { // 数组框架复制,但其中的元素不是复制而是引用 MarcNodeList temp = new MarcNodeList(); temp.add(target_nodes); target_nodes = temp; } // 先(从原有DOM位置)摘除当前集合内的全部元素 source_nodes.detach(); int i = 0; foreach (MarcNode target_node in target_nodes) { foreach (MarcNode source_node in source_nodes) { MarcNode source = source_node; if (i > 0) // 第一轮以后,源对象每个都要复制后插入目标位置 { source = source.clone(); target_node.prepend(source); } else target_node.prepend(source); } i++; } }
// 组合构造若干个856字段内容 static string BuildLinks(MarcNodeList fields) { StringBuilder text = new StringBuilder(4096); int i = 0; foreach (MarcNode field in fields) { MarcNodeList nodes = field.select("subfield"); if (nodes.count > 0) { string u = ""; MarcNodeList single = nodes.select("subfield[@name='u']"); if (single.count > 0) { u = single[0].Content; } string z = ""; single = nodes.select("subfield[@name='z']"); if (single.count > 0) { z = single[0].Content; } string t3 = ""; single = nodes.select("subfield[@name='3']"); if (single.count > 0) { t3 = single[0].Content; } if (i > 0) text.Append("|"); StringBuilder temp = new StringBuilder(4096); if (string.IsNullOrEmpty(t3) == false) temp.Append(t3 + ": <|"); temp.Append("url:" + u); temp.Append(" text:" + u); if (string.IsNullOrEmpty(z) == false) temp.Append("|> " + z); text.Append(temp.ToString().Trim()); i++; } } return text.ToString().Trim(); }
/* public MarcNode SelectSingleNode(string strXpath) { MarcNavigator nav = new MarcNavigator(this); XPathNodeIterator ni = nav.Select(strXpath); ni.MoveNext(); return ((MarcNavigator)ni.Current).Item.MarcNode; } * */ #if NO public MarcNodeList SelectNodes(string strPath) { string strFirstPart = GetFirstPart(ref strPath); if (strFirstPart == "/") { /* if (this.Parent == null) return this.SelectNodes(strPath); * */ return GetRootNode().SelectNodes(strPath); } if (strFirstPart == "..") { return this.Parent.SelectNodes(strPath); } if (strFirstPart == ".") { return this.SelectNodes(strPath); } // tagname[@attrname=''] string strTagName = ""; string strCondition = ""; int nRet = strFirstPart.IndexOf("["); if (nRet == -1) strTagName = strFirstPart; else { strCondition = strFirstPart.Substring(nRet + 1); if (strCondition.Length > 0) { // 去掉末尾的']' if (strCondition[strCondition.Length - 1] == ']') strCondition.Substring(0, strCondition.Length - 1); } strTagName = strFirstPart.Substring(0, nRet); } MarcNodeList results = new MarcNodeList(null); for (int i = 0; i < this.ChildNodes.Count; i++) { MarcNode node = this.ChildNodes[i]; Debug.Assert(node.Parent != null, ""); if (strTagName == "*" || node.Name == strTagName) { if (results.Parent == null) results.Parent = node.Parent; results.Add(node); } } if (String.IsNullOrEmpty(strPath) == true) { // 到了path的末级。用strFirstPart筛选对象 return results; } return results.SelectNodes(strPath); }
/// <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; }
// 创建 OPAC 详细页面中的对象资源显示局部 HTML。这是一个 <table> 片段 // 前导语 $3 // 链接文字 $y $f // URL $u // 格式类型 $q // 对象ID $8 // 对象尺寸 $s // 公开注释 $z public static string BuildObjectHtmlTable(string strMARC, string strRecPath, XmlElement maps_container, BuildObjectHtmlTableStyle style = BuildObjectHtmlTableStyle.HttpUrlHitCount | BuildObjectHtmlTableStyle.Template, string strMarcSyntax = "unimarc") { // Debug.Assert(false, ""); MarcRecord record = new MarcRecord(strMARC); MarcNodeList fields = record.select("field[@name='856']"); if (fields.count == 0) { return(""); } StringBuilder text = new StringBuilder(); text.Append("<table class='object_table'>"); text.Append("<tr class='column_title'>"); text.Append("<td class='type' style='word-break:keep-all;'>材料</td>"); text.Append("<td class='hitcount'></td>"); text.Append("<td class='link' style='word-break:keep-all;'>链接</td>"); text.Append("<td class='mime' style='word-break:keep-all;'>媒体类型</td>"); text.Append("<td class='size' style='word-break:keep-all;'>尺寸</td>"); text.Append("<td class='bytes' style='word-break:keep-all;'>字节数</td>"); text.Append("</tr>"); int nCount = 0; foreach (MarcField field in fields) { string x = field.select("subfield[@name='x']").FirstContent; Hashtable table = StringUtil.ParseParameters(x, ';', ':'); string strType = (string)table["type"]; // TODO: if (strType == null) { strType = ""; } if (string.IsNullOrEmpty(strType) == false && (style & BuildObjectHtmlTableStyle.FrontCover) == 0 && (strType == "FrontCover" || strType.StartsWith("FrontCover.") == true)) { continue; } string strSize = (string)table["size"]; string s_q = field.select("subfield[@name='q']").FirstContent; // 注意, FirstContent 可能会返回 null List <Map856uResult> u_list = new List <Map856uResult>(); { string u = field.select("subfield[@name='u']").FirstContent; // Hashtable parameters = new Hashtable(); if (maps_container != null && (style & BuildObjectHtmlTableStyle.Template) != 0) { // return: // -1 出错 // 0 没有发生宏替换 // 1 发生了宏替换 int nRet = Map856u(u, strRecPath, maps_container, // parameters, style, out u_list, // strUri, out string strError); //if (nRet == -1) // strUri = "!error:" + strError; if (nRet == -1) { u_list.Add(new Map856uResult { Result = "!error: 对 858$u 内容 '" + u + "' 进行映射变换时出错: " + strError }); } } else { u_list.Add(new Map856uResult { Result = u }); // WrapUrl == true ? } } foreach (Map856uResult result in u_list) { string strUri = MakeObjectUrl(strRecPath, result.Result); Hashtable parameters = result.Parameters; string strSaveAs = ""; if (string.IsNullOrEmpty(s_q) == true // || StringUtil.MatchMIME(s_q, "text") == true || StringUtil.MatchMIME(s_q, "image") == true) { } else { strSaveAs = "&saveas=true"; } string strHitCountImage = ""; string strObjectUrl = strUri; string strPdfUrl = ""; string strThumbnailUrl = ""; if (result.WrapUrl == true) { if (StringUtil.IsHttpUrl(strUri) == false) { // 内部对象 strObjectUrl = "./getobject.aspx?uri=" + HttpUtility.UrlEncode(strUri) + strSaveAs; strHitCountImage = "<img src='" + strObjectUrl + "&style=hitcount' alt='hitcount'></img>"; if (s_q == "application/pdf") { strPdfUrl = "./viewpdf.aspx?uri=" + HttpUtility.UrlEncode(strUri); strThumbnailUrl = "./getobject.aspx?uri=" + HttpUtility.UrlEncode(strUri + "/page:1,format=jpeg,dpi:24"); } } else { // http: 或 https: 的情形,即外部 URL if ((style & BuildObjectHtmlTableStyle.HttpUrlHitCount) != 0) { strObjectUrl = "./getobject.aspx?uri=" + HttpUtility.UrlEncode(strUri) + strSaveAs + "&biblioRecPath=" + HttpUtility.UrlEncode(strRecPath); strHitCountImage = "<img src='" + strObjectUrl + "&style=hitcount&biblioRecPath=" + HttpUtility.UrlEncode(strRecPath) + "' alt='hitcount'></img>"; } } } else { strObjectUrl = strUri; strHitCountImage = ""; } string linkText = ""; if (strMarcSyntax == "unimarc") { linkText = field.select("subfield[@name='2']").FirstContent; } else { linkText = field.select("subfield[@name='y']").FirstContent; } string f = field.select("subfield[@name='f']").FirstContent; string urlLabel = ""; if (string.IsNullOrEmpty(linkText) == false) { urlLabel = linkText; } else { urlLabel = f; } if (string.IsNullOrEmpty(urlLabel) == true) { urlLabel = strType; } // 2015/11/26 string s_z = field.select("subfield[@name='z']").FirstContent; if (string.IsNullOrEmpty(urlLabel) == true && string.IsNullOrEmpty(s_z) == false) { urlLabel = s_z; s_z = ""; } if (string.IsNullOrEmpty(urlLabel) == true) { urlLabel = strObjectUrl; } // if (StringUtil.StartsWith(strUri, "!error:")) { urlLabel += strUri; } // 2018/11/5 urlLabel = Map856uResult.MacroAnchorText(result.AnchorText, urlLabel); if (string.IsNullOrEmpty(strPdfUrl) == false && string.IsNullOrEmpty(urlLabel) == false) { strPdfUrl += "&title=" + HttpUtility.UrlEncode(urlLabel); } string urlTemp = ""; if (String.IsNullOrEmpty(strObjectUrl) == false) { string strParameters = ""; if (parameters != null) { foreach (string name in parameters.Keys) { strParameters += HttpUtility.HtmlAttributeEncode(name) + "='" + HttpUtility.HtmlAttributeEncode(parameters[name] as string) + "' "; // 注意,内容里面是否有单引号? } } urlTemp += "<a class='link' href='" + strObjectUrl + "' " + strParameters.Trim() + " >"; urlTemp += HttpUtility.HtmlEncode( (string.IsNullOrEmpty(strSaveAs) == false ? "下载 " : "") + urlLabel); urlTemp += "</a>"; if (string.IsNullOrEmpty(strPdfUrl) == false) { #if NO // 预览 按钮 urlTemp += "<br/><a href='" + strPdfUrl + "' target='_blank'>"; urlTemp += HttpUtility.HtmlEncode("预览 " + urlLabel); urlTemp += "</a>"; #endif // 缩略图 点按和预览按钮效果相同 urlTemp += "<br/><a class='thumbnail' href='" + strPdfUrl + "' target='_blank' alt='" + HttpUtility.HtmlEncode("在线阅读 " + urlLabel) + "'>"; urlTemp += "<img src='" + strThumbnailUrl + "' alt='" + HttpUtility.HtmlEncode("在线阅读 " + urlLabel) + "'></img>"; urlTemp += "</a>"; } } else { urlTemp = urlLabel; } // Different parts of the item are electronic, using subfield $3 to indicate the part (e.g., table of contents accessible in one file and an abstract in another) // 意思就是,如果有多种部分是电子资源,用 $3 指明当前 856 针对的哪个部分。这时候有多个 856,每个 856 中的 $3 各不相同 string s_3 = field.select("subfield[@name='3']").FirstContent; string s_s = field.select("subfield[@name='s']").FirstContent; text.Append("<tr class='content'>"); text.Append("<td class='type'>" + HttpUtility.HtmlEncode(s_3 + " " + strType) + "</td>"); text.Append("<td class='hitcount' style='text-align: right;'>" + strHitCountImage + "</td>"); text.Append("<td class='link' style='word-break:break-all;'>" + urlTemp + "</td>"); text.Append("<td class='mime'>" + HttpUtility.HtmlEncode(s_q) + "</td>"); text.Append("<td class='size'>" + HttpUtility.HtmlEncode(strSize) + "</td>"); text.Append("<td class='bytes'>" + HttpUtility.HtmlEncode(s_s) + "</td>"); text.Append("</tr>"); if (string.IsNullOrEmpty(s_z) == false) { text.Append("<tr class='comment'>"); text.Append("<td colspan='6'>" + HttpUtility.HtmlEncode(s_z) + "</td>"); text.Append("</tr>"); } nCount++; } } if (nCount == 0) { return(""); } text.Append("</table>"); return(text.ToString()); }
// 创建 table 中的对象资源局部 XML。这是一个 <table> 片段 // 前导语 $3 // 链接文字 $y $f // URL $u // 格式类型 $q // 对象ID $8 // 对象尺寸 $s // 公开注释 $z public static string BuildObjectXmlTable(string strMARC, // string strRecPath, BuildObjectHtmlTableStyle style = BuildObjectHtmlTableStyle.None) { // Debug.Assert(false, ""); MarcRecord record = new MarcRecord(strMARC); MarcNodeList fields = record.select("field[@name='856']"); if (fields.count == 0) { return(""); } XmlDocument dom = new XmlDocument(); dom.LoadXml("<table/>"); int nCount = 0; foreach (MarcField field in fields) { string x = field.select("subfield[@name='x']").FirstContent; Hashtable table = StringUtil.ParseParameters(x, ';', ':'); string strType = (string)table["type"]; if (string.IsNullOrEmpty(strType) == false && (style & BuildObjectHtmlTableStyle.FrontCover) == 0 && (strType == "FrontCover" || strType.StartsWith("FrontCover.") == true)) { continue; } string strSize = (string)table["size"]; string s_q = field.select("subfield[@name='q']").FirstContent; // 注意, FirstContent 可能会返回 null string u = field.select("subfield[@name='u']").FirstContent; // string strUri = MakeObjectUrl(strRecPath, u); string strSaveAs = ""; if (string.IsNullOrEmpty(s_q) == true || // 2016/9/4 StringUtil.MatchMIME(s_q, "text") == true || StringUtil.MatchMIME(s_q, "image") == true) { } else { strSaveAs = "true"; } string y = field.select("subfield[@name='y']").FirstContent; string f = field.select("subfield[@name='f']").FirstContent; string urlLabel = ""; if (string.IsNullOrEmpty(y) == false) { urlLabel = y; } else { urlLabel = f; } if (string.IsNullOrEmpty(urlLabel) == true) { urlLabel = strType; } // 2015/11/26 string s_z = field.select("subfield[@name='z']").FirstContent; if (string.IsNullOrEmpty(urlLabel) == true && string.IsNullOrEmpty(s_z) == false) { urlLabel = s_z; s_z = ""; } if (string.IsNullOrEmpty(urlLabel) == true) { urlLabel = u; } #if NO string urlTemp = ""; if (String.IsNullOrEmpty(strObjectUrl) == false) { urlTemp += "<a href='" + strObjectUrl + "'>"; urlTemp += urlLabel; urlTemp += "</a>"; } else { urlTemp = urlLabel; } #endif string s_3 = field.select("subfield[@name='3']").FirstContent; string s_s = field.select("subfield[@name='s']").FirstContent; XmlElement line = dom.CreateElement("line"); dom.DocumentElement.AppendChild(line); string strTypeString = (s_3 + " " + strType).Trim(); if (string.IsNullOrEmpty(strTypeString) == false) { line.SetAttribute("type", strTypeString); } if (string.IsNullOrEmpty(urlLabel) == false) { line.SetAttribute("urlLabel", urlLabel); } if (string.IsNullOrEmpty(u) == false) { line.SetAttribute("uri", u); } if (string.IsNullOrEmpty(s_q) == false) { line.SetAttribute("mime", s_q); } if (string.IsNullOrEmpty(strSize) == false) { line.SetAttribute("size", strSize); } if (string.IsNullOrEmpty(s_s) == false) { line.SetAttribute("bytes", s_s); } if (string.IsNullOrEmpty(strSaveAs) == false) { line.SetAttribute("saveAs", strSaveAs); } if (string.IsNullOrEmpty(s_z) == false) { line.SetAttribute("comment", s_z); } nCount++; } if (nCount == 0) { return(""); } return(dom.DocumentElement.OuterXml); }
/// <summary> /// 根据机内格式 MARC 字符串,创建若干 MarcField (或 MarcOuterField) 对象 /// </summary> /// <param name="strText">MARC 机内格式字符串</param> /// <param name="strOuterFieldDef">嵌套字段的定义。缺省为 null,表示不使用嵌套字段。这是一个列举字段名的逗号间隔的列表('*'为通配符),或者 '@' 字符后面携带一个正则表达式</param> /// <returns>新创建的 MarcField 对象集合</returns> public static MarcNodeList createFields( string strText, string strOuterFieldDef = null) { MarcNodeList results = new MarcNodeList(); List<string> segments = new List<string>(); StringBuilder field_text = new StringBuilder(4096); for (int i = 0; i < strText.Length; i++) { char ch = strText[i]; if (ch == 30 || ch == 29) { // 上一个字段结束 segments.Add(field_text.ToString()); field_text.Clear(); } else { field_text.Append(ch); } } // 剩余的内容 if (field_text.Length > 0) { segments.Add(field_text.ToString()); field_text.Clear(); } foreach (string segment in segments) { string strSegment = segment; // 如果长度不足 3 字符,补齐? if (strSegment.Length < 3) strSegment = strSegment.PadRight(3, '?'); // 创建头标区以后的普通字段 MarcNode field = null; if (string.IsNullOrEmpty(strOuterFieldDef) == false) { string strFieldName = strSegment.Substring(0, 3); // return: // -1 error // 0 not match // 1 match int nRet = MatchName(strFieldName, strOuterFieldDef); if (nRet == 1) field = new MarcOuterField(); else field = new MarcField(); } else field = new MarcField(); field.Text = strSegment; results.add(field); // Debug.Assert(field.Parent == parent, ""); } return results; }
// 把strText构造的新对象插入到this的后面。返回this /// <summary> /// 用指定的字符串构造出新的节点,插入到当前节点的后面兄弟位置 /// </summary> /// <param name="strText">用于构造新节点的字符串</param> /// <returns>当前节点</returns> public MarcNode after(string strText) { MarcNodeList targets = new MarcNodeList(this); targets.after(strText); return this; }
public override void OnRecord(object sender, StatisEventArgs e) { MarcNodeList nodes = null; string strContent = ""; MarcNodeList nodes1 = null; MarcRecord record = this.MarcRecord; string strClc = ""; string strNumber = ""; nodes = record.select("field[@name='690']/subfield[@name='a']"); foreach (MarcNode node in nodes) { strClc = node.Content; break; } nodes = record.select("field[@name='905']/subfield[@name='f']"); if (nodes.count == 0) { string strError = ""; string strAuthor = ""; List <string> results = null; nodes1 = record.select("field[@name='701']/subfield[@name='a']"); if (nodes1.count > 0) { goto FOUND; } nodes1 = record.select("field[@name='711']/subfield[@name='a']"); if (nodes1.count > 0) { goto FOUND; } nodes1 = record.select("field[@name='200']/subfield[@name='a']"); if (nodes1.count > 0) { goto FOUND; } FOUND: foreach (MarcNode node in nodes1) { strContent = node.Content; if (BiblioItemsHost.ContainHanzi(strContent)) { strAuthor = strContent; // 获得四角号码著者号 // return: // -1 error // 0 canceled // 1 succeed int nRet = GetSjhmAuthorNumber( strAuthor, out strNumber, out strError); if (nRet != 1) { } } break; } } else { return; } nodes = record.select("field[@name='905']/subfield[@name='a']"); // strStartEnd = String.Format("{0:000000}", intAutoNo); // intAutoNo = intAutoNo + 1; if (nodes.count > 0) { nodes[0].after(MarcQuery.SUBFLD + "d" + strClc + "/" + strNumber); } nodes = record.select("field[@name='906']/subfield[@name='a']"); if (nodes.count > 0) { foreach (MarcNode node in nodes) { node.after(MarcQuery.SUBFLD + "d" + strClc + "/" + strNumber); } } this.Changed = true; }
// 针对DOM树进行 XPath 筛选 // parameters: // nMaxCount 至多选择开头这么多个元素。-1表示不限制 /// <summary> /// 用 XPath 字符串选择节点 /// </summary> /// <param name="strXPath">XPath 字符串</param> /// <param name="nMaxCount">限制命中的最多节点数。-1表示不限制</param> /// <returns>被选中的节点集合</returns> public MarcNodeList select(string strXPath, int nMaxCount/* = -1*/) { MarcNodeList results = new MarcNodeList(); MarcNavigator nav = new MarcNavigator(this); // 出发点在当前对象 XPathNodeIterator ni = nav.Select(strXPath); while (ni.MoveNext() && (nMaxCount == -1 || results.count < nMaxCount)) { NaviItem item = ((MarcNavigator)ni.Current).Item; if (item.Type != NaviItemType.Element) { // if (bSkipNoneElement == false) throw new Exception("xpath '"+strXPath+"' 命中了非元素类型的节点,这是不允许的"); continue; } results.add(item.MarcNode); } return results; }
// 是否至少有一个内容非空? static bool AtLeastOneNotEmpty(MarcNodeList nodes) { foreach (MarcNode subfield in nodes) { if (string.IsNullOrEmpty(subfield.Content) == false) return true; } return false; }
/// <summary> /// 获得封面图像 URL /// 优先选择中等大小的图片 /// </summary> /// <param name="strMARC">MARC机内格式字符串</param> /// <param name="strPreferredType">优先使用何种大小类型</param> /// <returns>返回封面图像 URL。空表示没有找到</returns> public static string GetCoverImageUrl(string strMARC, string strPreferredType = "MediumImage") { string strLargeUrl = ""; string strMediumUrl = ""; // type:FrontCover.MediumImage string strUrl = ""; // type:FronCover string strSmallUrl = ""; MarcRecord record = new MarcRecord(strMARC); MarcNodeList fields = record.select("field[@name='856']"); 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 strType = (string)table["type"]; if (string.IsNullOrEmpty(strType) == true) { continue; } string u = field.select("subfield[@name='u']").FirstContent; // if (string.IsNullOrEmpty(u) == true) // u = field.select("subfield[@name='8']").FirstContent; // . 分隔 FrontCover.MediumImage if (StringUtil.HasHead(strType, "FrontCover." + strPreferredType) == true) { return(u); } if (StringUtil.HasHead(strType, "FrontCover.SmallImage") == true) { strSmallUrl = u; } else if (StringUtil.HasHead(strType, "FrontCover.MediumImage") == true) { strMediumUrl = u; } else if (StringUtil.HasHead(strType, "FrontCover.LargeImage") == true) { strLargeUrl = u; } else if (StringUtil.HasHead(strType, "FrontCover") == true) { strUrl = u; } } if (string.IsNullOrEmpty(strLargeUrl) == false) { return(strLargeUrl); } if (string.IsNullOrEmpty(strMediumUrl) == false) { return(strMediumUrl); } if (string.IsNullOrEmpty(strUrl) == false) { return(strUrl); } return(strSmallUrl); }
// 开始转bdf private void button_tobdf_Click(object sender, EventArgs e) { if (textBox_isofilename.Text.Trim() == "") { MessageBox.Show(this, "尚未选择iso数据文件"); return; } if (comboBox_source.Text.Trim() == "") { MessageBox.Show(this, "尚未选择数据来源系统"); return; } if (this.comboBox_source.Text.ToUpper() == "DT1000") { if (this.Location == "") { MessageBox.Show(this, "请输入馆藏地"); return; } if (this.BookType == "") { MessageBox.Show(this, "请输入图书类型"); return; } } // 选择保存的bdf文件 SaveFileDialog dlg = new SaveFileDialog() { Title = "书目转储文件名", Filter = "书目转储文件(*.bdf)|*.bdf", RestoreDirectory = true }; if (dlg.ShowDialog(this) != DialogResult.OK) { return; } // bdf文件是一个xml结构 string bdfFile = dlg.FileName; XmlTextWriter _writer = null; _writer = new XmlTextWriter(bdfFile, Encoding.UTF8) { Formatting = Formatting.Indented, Indentation = 4 }; _writer.WriteStartDocument(); _writer.WriteStartElement("dprms", "collection", DpNs.dprms); _writer.WriteAttributeString("xmlns", "dprms", null, DpNs.dprms); // 输出一个错误信息文件 FileInfo fileInfo = new FileInfo(bdfFile); string strSourceDir = fileInfo.DirectoryName; string errorFilename = strSourceDir + "\\~error.txt"; long errorCount1 = 0; StreamWriter sw_error = new StreamWriter(errorFilename, false, // append Encoding.UTF8); // 源iso文件 string isoFileName = this.textBox_isofilename.Text.Trim(); // 用当前日期作为批次号 string strBatchNo = DateTime.Now.ToString("yyyyMMdd"); int nIndex = 0; string strError = ""; MarcLoader loader = new MarcLoader(isoFileName, this.Encoding, "marc", null); foreach (string marc in loader) { MarcRecord record = new MarcRecord(marc); string strISBN = record.select("field[@name='010']/subfield[@name='a']").FirstContent; strISBN = string.IsNullOrEmpty(strISBN) ? "" : strISBN; string strTitle = record.select("field[@name='200']/subfield[@name='a']").FirstContent; strTitle = string.IsNullOrEmpty(strTitle) ? "" : strTitle; string strSummary = strISBN + "\t" + strTitle; // 转换回XML XmlDocument domMarc = null; int nRet = MarcUtil.Marc2Xml(marc, this.MarcSyntax,//this.m_strBiblioSyntax, out domMarc, out strError); if (nRet == -1) { errorCount1++; sw_error.WriteLine("!!!异常Marc2Xml()" + strError); return; } // 写<record> _writer.WriteStartElement("dprms", "record", DpNs.dprms); // 写<biblio> _writer.WriteStartElement("dprms", "biblio", DpNs.dprms); // 把marc xml写入<biblio>下级 domMarc.WriteTo(_writer); // </<biblio>> _writer.WriteEndElement(); #region 关于价格 bool bPriceError = false; // *** 从010$d中取得价格 string strErrorPrice = ""; string strCataPrice = record.select("field[@name='010']/subfield[@name='d']").FirstContent; string strOldPrice = strCataPrice; // marc中不存在010$d价格 if (string.IsNullOrEmpty(strCataPrice) == true) { strCataPrice = "CNY0"; sw_error.WriteLine(nIndex + "\t" + strSummary + "\t不存在010$d价格子字段。"); bPriceError = true; } else { // 如果不在合法的价格格式 if (!Regex.IsMatch(strCataPrice, @"^(CNY)?\d+\.?\d{0,2}$")) { //将价格中含有的汉字型数值替换为数字 strCataPrice = ParsePrice(strCataPrice); if (strCataPrice != strOldPrice) { strErrorPrice = strOldPrice; sw_error.WriteLine(nIndex + "\t" + strSummary + "\t价格字符串 '" + strOldPrice + "' 被自动修改为 '" + strCataPrice + "'"); bPriceError = true; } //已知格式价格内容转换 string temp1 = strCataPrice; strCataPrice = CorrectPrice(strCataPrice); if (strCataPrice != temp1) { strErrorPrice = strOldPrice; sw_error.WriteLine(nIndex + "\t" + strSummary + "\t价格字符串 '" + strOldPrice + "' 被自动修改为 '" + strCataPrice + "'"); bPriceError = true; } } List <string> temp = VerifyPrice(strCataPrice); if (temp.Count > 0) { string temp1 = strCataPrice; CorrectPrice(ref strCataPrice); if (temp1 != strCataPrice) { if (IsPriceCorrect(strCataPrice) == true) { sw_error.WriteLine(nIndex + "\t" + strSummary + "\t价格字符串 '" + strOldPrice + "' 被自动修改为 '" + strCataPrice + "'"); bPriceError = true; } else { strCataPrice = "CNY0"; strErrorPrice = strOldPrice; sw_error.WriteLine(nIndex + "\t" + strSummary + "\t价格字符串 '" + strOldPrice + "' 无法被自动修改,默认为 CNY0"); bPriceError = true; } } else { strCataPrice = "CNY0"; strErrorPrice = strOldPrice; sw_error.WriteLine(nIndex + "\t" + strSummary + "\t价格字符串 '" + strOldPrice + "' 无法被自动修改,默认为 CNY0"); bPriceError = true; } } // 如果不是CNY开头的,加CNY if (!strCataPrice.StartsWith("CNY")) { strCataPrice = "CNY" + strCataPrice; sw_error.WriteLine(nIndex + ":" + strSummary + "*** 价格字符串 '" + strCataPrice + "' 不含有币种前缀,自动添加为'CNY'\r\n"); bPriceError = true; } } // 如果价格经过修复,错误记录数增加1 if (bPriceError == true) { errorCount1++; } #endregion #region 从905$d$e取得索书号 // 905$d 中图法大类 string str905d = record.select("field[@name='905']/subfield[@name='d']").FirstContent; if (String.IsNullOrEmpty(str905d) == true) { strError = nIndex + "\t" + strSummary + "\t905字段不存在$d子字段"; sw_error.WriteLine(strError); } // 905$e 种次号 string str905e = record.select("field[@name='905']/subfield[@name='e']").FirstContent; if (String.IsNullOrEmpty(str905e) == true) { strError = nIndex + "\t" + strSummary + "\t905字段不存在$e子字段"; sw_error.WriteLine(strError); } // 如果缺索取号记一笔 if (bPriceError == false) { if (string.IsNullOrEmpty(str905d) == true || string.IsNullOrEmpty(str905e) == true) { errorCount1++; } } #endregion // 册条码是放在906$h字段的 MarcNodeList subfield_690h = record.select("field[@name='906']/subfield[@name='h']"); int index = 0; // <itemCollection> _writer.WriteStartElement("dprms", "itemCollection", DpNs.dprms); foreach (MarcNode node in subfield_690h) { index++; string strBarcode = node.Content; // 册条码号为空,则不创建册信息元素 if (string.IsNullOrEmpty(strBarcode)) { continue; } _writer.WriteStartElement("dprms", "item", DpNs.dprms); strBarcode = strBarcode.Trim(); _writer.WriteElementString("barcode", strBarcode); string strLocation = this.Location; //DT1000使用界面输入的值 _writer.WriteElementString("location", strLocation); if (!string.IsNullOrEmpty(strCataPrice)) { _writer.WriteElementString("price", strCataPrice); } if (!string.IsNullOrEmpty(strErrorPrice)) { _writer.WriteElementString("comment", "原价格:" + strErrorPrice); } string strBookType = this.BookType;//DT1000使用界面输入的值 _writer.WriteElementString("bookType", strBookType); if (!string.IsNullOrEmpty(str905d) && !string.IsNullOrEmpty(str905e)) { _writer.WriteElementString("accessNo", str905d + "/" + str905e); } else { //strError = nIndex + "\t" + strSummary + "\t册记录'" + strBarcode + "'不含有 索取号 内容"; //sw_error.WriteLine(strError); } _writer.WriteElementString("batchNo", strBatchNo);// _writer.WriteEndElement(); } //</itemCollection> _writer.WriteEndElement(); //</record> _writer.WriteEndElement(); nIndex++; this._mainForm.SetStatusMessage(nIndex.ToString() + " " + strSummary); Application.DoEvents(); } //</collection> _writer.WriteEndElement(); _writer.WriteEndDocument(); _writer.Close(); _writer = null; this._mainForm.SetStatusMessage("处理完成,共处理" + nIndex.ToString() + "条。"); string strMsg = "数据转换处理结束。请到dp2内务使用【批处理】-【从书目转储文件导入】功能将转换的 书目转储文件 导入到目标书目库。"; MessageBox.Show(this, strMsg); if (sw_error != null) { strMsg = "共处理'" + nIndex + "'条MARC记录,其中有 " + errorCount1.ToString() + " 条记录中有错误信息。"; sw_error.WriteLine(strMsg); sw_error.Close(); sw_error = null; } }
// 创建 table 中的对象资源局部 XML。这是一个 <table> 片段 // 前导语 $3 // 链接文字 $y $f // URL $u // 格式类型 $q // 对象ID $8 // 对象尺寸 $s // 公开注释 $z public static string BuildObjectXmlTable(string strMARC, // string strRecPath, BuildObjectHtmlTableStyle style = BuildObjectHtmlTableStyle.None, string strMarcSyntax = "unimarc", string strRecPath = null, XmlElement maps_container = null) { // Debug.Assert(false, ""); MarcRecord record = new MarcRecord(strMARC); MarcNodeList fields = record.select("field[@name='856']"); if (fields.count == 0) { return(""); } XmlDocument dom = new XmlDocument(); dom.LoadXml("<table/>"); int nCount = 0; foreach (MarcField field in fields) { string x = field.select("subfield[@name='x']").FirstContent; Hashtable table = StringUtil.ParseParameters(x, ';', ':'); string strType = (string)table["type"]; if (strType == null) { strType = ""; } if (string.IsNullOrEmpty(strType) == false && (style & BuildObjectHtmlTableStyle.FrontCover) == 0 && (strType == "FrontCover" || StringUtil.StartsWith(strType, "FrontCover.") == true)) { continue; } string strSize = (string)table["size"]; string s_q = field.select("subfield[@name='q']").FirstContent; // 注意, FirstContent 可能会返回 null List <Map856uResult> u_list = new List <Map856uResult>(); { string u = field.select("subfield[@name='u']").FirstContent; // 2018/10/24 // Hashtable parameters = new Hashtable(); if (maps_container != null && (style & BuildObjectHtmlTableStyle.Template) != 0) { // string strUri = MakeObjectUrl(strRecPath, u); // return: // -1 出错 // 0 没有发生宏替换 // 1 发生了宏替换 int nRet = Map856u(u, strRecPath, maps_container, style, // parameters, out u_list, out string strError); if (nRet == -1) { u_list.Add(new Map856uResult { Result = "!error: 对 858$u 内容 '" + u + "' 进行映射变换时出错: " + strError }); } } else { u_list.Add(new Map856uResult { Result = u }); // WrapUrl == true ? } } string strSaveAs = ""; if (string.IsNullOrEmpty(s_q) == true || // 2016/9/4 StringUtil.MatchMIME(s_q, "text") == true || StringUtil.MatchMIME(s_q, "image") == true) { } else { strSaveAs = "true"; } #if NO string y = field.select("subfield[@name='y']").FirstContent; string f = field.select("subfield[@name='f']").FirstContent; string urlLabel = ""; if (string.IsNullOrEmpty(y) == false) { urlLabel = y; } else { urlLabel = f; } if (string.IsNullOrEmpty(urlLabel) == true) { urlLabel = strType; } #endif string linkText = ""; if (strMarcSyntax == "unimarc") { linkText = field.select("subfield[@name='2']").FirstContent; } else { linkText = field.select("subfield[@name='y']").FirstContent; } string f = field.select("subfield[@name='f']").FirstContent; string urlLabel = ""; if (string.IsNullOrEmpty(linkText) == false) { urlLabel = linkText; } else { urlLabel = f; } if (string.IsNullOrEmpty(urlLabel) == true) { urlLabel = strType; } // 2015/11/26 string s_z = field.select("subfield[@name='z']").FirstContent; if (string.IsNullOrEmpty(urlLabel) == true && string.IsNullOrEmpty(s_z) == false) { urlLabel = s_z; s_z = ""; } #if NO string urlTemp = ""; if (String.IsNullOrEmpty(strObjectUrl) == false) { urlTemp += "<a href='" + strObjectUrl + "'>"; urlTemp += urlLabel; urlTemp += "</a>"; } else { urlTemp = urlLabel; } #endif string s_3 = field.select("subfield[@name='3']").FirstContent; string s_s = field.select("subfield[@name='s']").FirstContent; foreach (Map856uResult u in u_list) { XmlElement line = dom.CreateElement("line"); dom.DocumentElement.AppendChild(line); string strTypeString = (s_3 + " " + strType).Trim(); if (string.IsNullOrEmpty(strTypeString) == false) { line.SetAttribute("type", strTypeString); } string currentUrlLabel = urlLabel; if (string.IsNullOrEmpty(currentUrlLabel) == true) { if (u.AnchorText != null) { currentUrlLabel = Map856uResult.MacroAnchorText(u.AnchorText, currentUrlLabel); } else { currentUrlLabel = u.Result; } } else { if (u.AnchorText != null) { currentUrlLabel = Map856uResult.MacroAnchorText(u.AnchorText, urlLabel); } } if (string.IsNullOrEmpty(currentUrlLabel) == false) { line.SetAttribute("urlLabel", currentUrlLabel); } if (string.IsNullOrEmpty(u.Result) == false) { line.SetAttribute("uri", u.Result); } if (u.Parameters != null && u.Parameters.Count > 0) { line.SetAttribute("uriEnv", StringUtil.BuildParameterString(u.Parameters, ',', '=', "url")); } if (string.IsNullOrEmpty(s_q) == false) { line.SetAttribute("mime", s_q); } if (string.IsNullOrEmpty(strSize) == false) { line.SetAttribute("size", strSize); } if (string.IsNullOrEmpty(s_s) == false) { line.SetAttribute("bytes", s_s); } if (string.IsNullOrEmpty(strSaveAs) == false) { line.SetAttribute("saveAs", strSaveAs); } if (string.IsNullOrEmpty(s_z) == false) { line.SetAttribute("comment", s_z); } nCount++; } } if (nCount == 0) { return(""); } return(dom.DocumentElement.OuterXml); }
public override void OnRecord(object sender, StatisEventArgs e) { MarcNodeList nodes = null; string strContent = ""; MarcNodeList nodes1 = null; MarcNode node2 = null; MarcRecord record = this.MarcRecord; if (record.Header[5, 4] == "nam ") { record.Header[5, 4] = "oam2"; } //有010的 nodes = record.select("field[@name='010']/subfield[@name='b']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } if (strContent == "光盘") { node2 = node.Parent; if (node2.FirstChild.Name == "a") { strContent = node2.FirstChild.Content; //node2.Content = "{cr:CALIS}" + node2.Content; node2.after("307 " + MarcQuery.SUBFLD + "a附光盘:ISBN " + strContent); node2.detach(); this.Changed = true; } } } //有016的 nodes = record.select("field[@name='016']/subfield[@name='b']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } if (strContent == "磁带") { node2 = node.Parent; if (node2.FirstChild.Name == "a") { strContent = node2.FirstChild.Content; //node2.Content = "{cr:CALIS}" + node2.Content; node2.after("307 {cr:NLC}" + MarcQuery.SUBFLD + "a附磁带:" + strContent); node2.detach(); this.Changed = true; } } } //有100的 nodes = record.select("field[@name='100']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } if (strContent.Substring(28, 4) == "0120") { node.Content = strContent.Substring(0, 28) + "0110" + strContent.Substring(32, strContent.Length - 32); this.Changed = true; } } //都存在的拼音 nodes = record.select("field[@name='200' or @name='512' or @name='513' or @name='514' or @name='515' or @name='516' or @name='517' or @name='518' or @name='540' or @name='541' or @name='545' or @name='701' or @name='702' or @name='711' or @name='712' or @name='730']/subfield[@name='A']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } node.Name = "9"; node.Content = node.Content.ToLower(); this.Changed = true; } //国图不存在的拼音 nodes = record.select("field[@name='225' or @name='600' or @name='601' or @name='604' or @name='605' or @name='606' or @name='607' or @name='610']/subfield[@name='A']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } node.detach(); this.Changed = true; } //有200$d的 nodes = record.select("field[@name='200']/subfield[@name='d']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } if (strContent.StartsWith("= ")) { node.Content = strContent.Remove(0, 2); this.Changed = true; } } //有200$f$g的 nodes = record.select("field[@name='200']/subfield[@name='f' or @name='g']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } if (BiblioItemsHost.ContainHanzi(strContent)) { string strRight = strContent.Replace(",", ","); strRight = strRight.Replace(" ", ""); node.Content = strRight.Replace("...", ""); this.Changed = true; } } //有205的 nodes = record.select("field[@name='205']/subfield[@name='a']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } if (strContent.IndexOf("第") >= 0) { string strRight = strContent.Replace("第", ""); node.Content = strRight; this.Changed = true; } } //有215$a的 nodes = record.select("field[@name='215']/subfield[@name='a']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } if (strContent.IndexOf(" ") >= 0) { string strRight = strContent.Replace(" ", ""); node.Content = strRight; this.Changed = true; } } //有215$e的 nodes = record.select("field[@name='215']/subfield[@name='e']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } if (strContent.IndexOf("光盘") >= 0) { string strRight = strContent.Replace("光盘", ""); node.Content = strRight.Replace("片", "光盘"); this.Changed = true; } } //有215$d的 nodes = record.select("field[@name='215']/subfield[@name='d']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } if (strContent.IndexOf("x") >= 0) { string strRight = strContent.Replace("x", "×"); node.Content = strRight; this.Changed = true; } } //有410的 nodes = record.select("field[@name='410']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } if (strContent.IndexOf(MarcQuery.SUBFLD + "i") >= 0) { node.Name = "462"; } else { node.Name = "461"; } this.Changed = true; } //有605$a的 nodes = record.select("field[@name='605']/subfield[@name='a']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } if (strContent.IndexOf("《") < 0) { node.Content = "《" + strContent + "》"; this.Changed = true; } } //有600/701/702的 nodes = record.select("field[@name='600' or @name='701' or @name='702']"); foreach (MarcNode node in nodes) { strContent = node.Content; if (String.IsNullOrEmpty(strContent)) { continue; } MarcNodeList subfields = node.select("subfield[@name='g' or @name='f']"); if (subfields.count > 0) { foreach (MarcNode node3 in node.ChildNodes) { if (node3.Name == "g") { node3.Name = "c"; } if (node3.Name == "f") { node3.Content = "(" + node3.Content + ")"; } } for (int i = node.ChildNodes.count - 1; i >= 0; i--) { MarcNode node3 = node.ChildNodes[i]; strContent = node3.Content; bool prefix = false; if (node3.Name == "f") { prefix = true; } else { if (prefix) { if (strContent.Substring(strContent.Length - 1, 1) == ",") { node3.Content = strContent.Remove(strContent.Length - 1, 1); } } prefix = false; } } for (int i = 0; i < node.ChildNodes.count; i++) { MarcNode node3 = node.ChildNodes[i]; strContent = node3.Content; bool prefix = false; if (strContent.StartsWith("(")) { if (prefix) { node3.Content = strContent.Remove(0, 1); strContent = node.ChildNodes[i - 1].Content; node.ChildNodes[i - 1].Content = strContent.Substring(0, strContent.Length - 1); } prefix = true; } else { prefix = false; } } this.Changed = true; } } record.Fields.sort(); this.Changed = true; }