// 针对一个 key 字符串进行检索 // parameters: // strMatchStyle auto_expand/exact/left 分别是自动截断探索/精确一致/前方一致 // strStyle expand_all_search 表示需要扩展检索。即截断后面若干位以后检索。如果没有这个值,表示使用精确检索 // exact_match 表示精确一致检索。当 exact_match 结合上 expand_all_search 时,中途都是前方一致的,最后一次才会精确一致 // strOutputKey [out]经过加工后的 key。可能和 strKey 内容不同 // return: // -1 出错 // 0 成功 int SearchOneKey( Relation relation, string strKey, // string strStyle, string strMatchStyle, out string strOutputKey, out List<ResultItem> results, out string strError) { strError = ""; results = new List<ResultItem>(); strOutputKey = strKey; if (string.IsNullOrEmpty(strKey) == true) { strError = "strKey 不能为空"; return -1; } #if NO bool bExpandAllSearch = StringUtil.IsInList("expand_all_search", strStyle); bool bExpandSearch = StringUtil.IsInList("expand_search", strStyle); bool bExactMatch = StringUtil.IsInList("exact_match", strStyle); if (bExpandAllSearch == true && bExpandSearch == true) { strError = "strStyle 参数中 expand_all_search 和 expand_search 只能使用其中一个"; return -1; } // 需要执行检索的 key 的数组 // List<string> keys = new List<string>(); List<SearchItem> keys = new List<SearchItem>(); if (bExpandAllSearch == true) { #if NO // 如要实现扩展检索,则先把全部可能的级次的 key 都准备好 for (int i = 1; i < strKey.Length; i++) { keys.Add(strKey.Substring(0, i)); } #endif for (int i = strKey.Length; i > 0; i--) { if (i == strKey.Length) { SearchItem key = new SearchItem(); key.Key = strKey; key.MatchStyle = "exact"; keys.Add(key); } { SearchItem key = new SearchItem(); key.Key = strKey.Substring(0, i); key.MatchStyle = "left"; keys.Add(key); } } } else if (bExpandSearch == true) { // 先检索较长的 key for (int i = strKey.Length; i > 0; i--) { if (i == strKey.Length) { SearchItem key = new SearchItem(); key.Key = strKey; key.MatchStyle = "exact"; key.Style = "stop"; keys.Add(key); } { SearchItem key = new SearchItem(); key.Key = strKey.Substring(0, i); key.MatchStyle = "left"; if (i < strKey.Length) key.Style = "stop"; // 命中则停止探索 else key.Style = ""; // 如果是最长的 key,则不精确检索即便命中也不停止后面的继续探索 keys.Add(key); } } } else { { SearchItem key = new SearchItem(); key.Key = strKey; key.MatchStyle = "exact"; key.Style = "stop"; keys.Add(key); } } #endif List<SearchItem> keys = new List<SearchItem>(); if (strMatchStyle == "exact" || strMatchStyle == "left") { SearchItem key = new SearchItem(); key.Key = strKey; key.MatchStyle = strMatchStyle; // "exact"; key.Style = "stop"; keys.Add(key); } else if (strMatchStyle == "auto_expand") { // 先检索较长的 key for (int i = strKey.Length; i > 0; i--) { if (i == strKey.Length) { SearchItem key = new SearchItem(); key.Key = strKey; key.MatchStyle = "exact"; key.Style = "stop"; keys.Add(key); } { SearchItem key = new SearchItem(); key.Key = strKey.Substring(0, i); key.MatchStyle = "left"; if (i < strKey.Length) key.Style = "stop"; // 命中则停止探索 else key.Style = ""; // 如果是最长的 key,则不精确检索即便命中也不停止后面的继续探索 keys.Add(key); } } } else { strError = "无法识别的 strMatchStyle ["+strMatchStyle+"]"; return -1; } // 用于去重 Hashtable recpath_table = new Hashtable(); { int i = 0; foreach (SearchItem key in keys) { Application.DoEvents(); if (_stop.State != 0) { this.Stopped = true; strError = "中断"; return -1; } // string strPartKey = strKey.Substring(0, i); List<string> temp_results = new List<string>(); // return: // -1 出错 // 0 没有找到 // >0 命中的条数 int nRet = Search(relation.DbName, key.Key, key.MatchStyle, // "left", MaxHitCount + 1, ref temp_results, out strError); if (nRet == -1) return -1; // 去重并加入最后集合 foreach (string s in temp_results) { string strRecPath = ""; string strXml = ""; StringUtil.ParseTwoPart(s, "|", out strRecPath, out strXml); if (recpath_table.ContainsKey(strRecPath) == true) continue; recpath_table.Add(strRecPath, 1); ResultItem item = new ResultItem(); item.RecPath = strRecPath; item.Xml = strXml; results.Add(item); } if (key.Style == "stop" && nRet > 0) { strOutputKey = key.Key; // 实际命中的 key break; } #if NO // 在扩展检索情形下,如果一次检索命中结果超过极限,说明还需要继续检索下一个 key(这是担心结果集不足以概括更下级的类目)。继续检索下去直到一次检索的结果数量小于极限 if (bExpandAllSearch == true && nRet < MaxHitCount + 1) break; #endif i++; } } return 0; }
// 构建集合对象 // 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); }
// 构建集合对象 // 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; }