// 构造一个检索词的XML检索式局部 // 本函数不递归 // return: // -1 出错 // 0 数据库没有找到 // 1 成功 static int BuildOneXml( ZHostInfo zhost, List <string> dbnames, string strTerm, long lAttritueValue, out string strQueryXml, out string strError) { strQueryXml = ""; try { strError = ""; if (dbnames.Count == 0) { strError = "一个数据库名也未曾指定"; return(-1); } // string strFrom = ""; // 根据nAttributeType nAttributeValue得到检索途径名 // 先评估一下,是不是每个数据库都有一样的maxResultCount参数。 // 如果是,则可以把这些数据库都组合为一个<target>; // 如果不是,则把相同的挑选出来成为一个<target>,然后多个<target>用OR组合起来 // 为此,可以先把数据库属性对象按照maxResultCount参数排序,以便聚合是用<target>。 // 但是这带来一个问题:最后发生的检索库的先后顺序,就不是用户要求的那个顺序了。 // 看来,还得按照用户指定的数据库顺序来构造<item>。那么,就不得不降低聚合的可能, // 而仅仅聚合相邻的、maxResultCount值相同的那些 int nPrevMaxResultCount = -1; // 前一个MaxResultCount参数值 List <List <BiblioDbProperty> > prop_groups = new List <List <BiblioDbProperty> >(); List <BiblioDbProperty> props = new List <BiblioDbProperty>(); for (int i = 0; i < dbnames.Count; i++) { string strDbName = dbnames[i]; BiblioDbProperty prop = zhost.GetDbProperty(strDbName, true); if (prop == null) { strError = "数据库 '" + strDbName + "' 不存在"; return(0); } // 如果当前库的MaxResultCount参数和前面紧邻的不一样了,则需要推入当前正在使用的props,新起一个props if (prop.MaxResultCount != nPrevMaxResultCount && props.Count != 0) { Debug.Assert(props.Count > 0, "不为空的props才能推入 (1)"); prop_groups.Add(props); props = new List <BiblioDbProperty>(); // 新增加一个props } props.Add(prop); nPrevMaxResultCount = prop.MaxResultCount; } Debug.Assert(props.Count > 0, "不为空的props才能推入 (2)"); prop_groups.Add(props); // 将最后一个props加入到group数组中 for (int i = 0; i < prop_groups.Count; i++) { props = prop_groups[i]; string strTargetListValue = ""; int nMaxResultCount = -1; for (int j = 0; j < props.Count; j++) { BiblioDbProperty prop = props[j]; string strDbName = prop.DbName; #if DEBUG if (j != 0) { Debug.Assert(prop.MaxResultCount == nMaxResultCount, "props内的每个数据库都应当有相同的MaxResultCount参数值"); } #endif if (j == 0) { nMaxResultCount = prop.MaxResultCount; // 只取第一个prop的值即可 } string strFrom = zhost.GetFromName(strDbName, lAttritueValue, out string strOutputDbName, out strError); if (strFrom == null) { return(-1); // 寻找from名的过程发生错误 } if (strTargetListValue != "") { strTargetListValue += ";"; } Debug.Assert(strOutputDbName != "", ""); strTargetListValue += strOutputDbName + ":" + strFrom; } if (i != 0) { strQueryXml += "<operator value='OR' />"; } strQueryXml += "<target list='" + strTargetListValue + "'>" + "<item><word>" + SecurityElement.Escape(strTerm) + "</word><match>left</match><relation>=</relation><dataType>string</dataType>" + "<maxCount>" + nMaxResultCount.ToString() + "</maxCount></item>" + "<lang>zh</lang></target>"; } // 如果有多个props,则需要在检索XML外面包裹一个<target>元素,以作为一个整体和其他部件进行逻辑操作 if (prop_groups.Count > 1) { strQueryXml = "<target>" + strQueryXml + "</target>"; } return(1); } catch (Exception ex) { strError = ex.Message; return(-1); } }
// 构造一个检索词的XML检索式局部 // 本函数不递归 // return: // -1 出错 // 0 数据库没有找到 // 1 成功 static int BuildOneXml( ZHostInfo zhost, List <string> dbnames, string strTerm, long lAttritueValue, out string strQueryXml, out string strError) { strQueryXml = ""; try { strError = ""; if (dbnames.Count == 0) { strError = "一个数据库名也未曾指定"; return(-1); } // string strFrom = ""; // 根据nAttributeType nAttributeValue得到检索途径名 // 先评估一下,是不是每个数据库都有一样的maxResultCount参数。 // 如果是,则可以把这些数据库都组合为一个<target>; // 如果不是,则把相同的挑选出来成为一个<target>,然后多个<target>用OR组合起来 // 为此,可以先把数据库属性对象按照maxResultCount参数排序,以便聚合是用<target>。 // 但是这带来一个问题:最后发生的检索库的先后顺序,就不是用户要求的那个顺序了。 // 看来,还得按照用户指定的数据库顺序来构造<item>。那么,就不得不降低聚合的可能, // 而仅仅聚合相邻的、maxResultCount值相同的那些 int nPrevMaxResultCount = -1; // 前一个MaxResultCount参数值 List <List <BiblioDbProperty> > prop_groups = new List <List <BiblioDbProperty> >(); List <BiblioDbProperty> props = new List <BiblioDbProperty>(); for (int i = 0; i < dbnames.Count; i++) { string strDbName = dbnames[i]; BiblioDbProperty prop = zhost.GetDbProperty(strDbName, true); if (prop == null) { strError = "数据库 '" + strDbName + "' 不存在"; return(0); } // 如果当前库的MaxResultCount参数和前面紧邻的不一样了,则需要推入当前正在使用的props,新起一个props if (prop.MaxResultCount != nPrevMaxResultCount && props.Count != 0) { Debug.Assert(props.Count > 0, "不为空的props才能推入 (1)"); prop_groups.Add(props); props = new List <BiblioDbProperty>(); // 新增加一个props } props.Add(prop); nPrevMaxResultCount = prop.MaxResultCount; } Debug.Assert(props.Count > 0, "不为空的props才能推入 (2)"); prop_groups.Add(props); // 将最后一个props加入到group数组中 // 没有找到 From 的列表 // use编号 --> 关于没有找到的报错字符串 Hashtable notFoundTable = new Hashtable(); for (int i = 0; i < prop_groups.Count; i++) { props = prop_groups[i]; string strTargetListValue = ""; int nMaxResultCount = -1; for (int j = 0; j < props.Count; j++) { BiblioDbProperty prop = props[j]; string strDbName = prop.DbName; #if DEBUG if (j != 0) { Debug.Assert(prop.MaxResultCount == nMaxResultCount, "props内的每个数据库都应当有相同的MaxResultCount参数值"); } #endif if (j == 0) { nMaxResultCount = prop.MaxResultCount; // 只取第一个prop的值即可 } /* * string strFrom = zhost.GetFromName(strDbName, * lAttritueValue, * out string strOutputDbName, * out strError); * if (strFrom == null) * return -1; // 寻找from名的过程发生错误 */ var result = zhost.GetFromName(strDbName, lAttritueValue); if (result.Value == -1) { // 2020/5/23 // 如果是 use 没有找到,这里暂时不急于判断。如果后面找到了至少一次,就不报错;否则(就是说一次都没有找到)就要报错 if (result.ErrorCode == "useNotFound") { notFoundTable[$"{lAttritueValue}"] = result.ErrorInfo; continue; } strError = result.ErrorInfo; return(-1); } if (strTargetListValue != "") { strTargetListValue += ";"; } Debug.Assert(string.IsNullOrEmpty(result.DbName) == false, ""); Debug.Assert(string.IsNullOrEmpty(result.From) == false, ""); strTargetListValue += result.DbName + ":" + result.From; } if (string.IsNullOrEmpty(strTargetListValue)) { continue; } if (i != 0) { strQueryXml += "<operator value='OR' />"; } strQueryXml += "<target list='" + strTargetListValue + "'>" + "<item><word>" + SecurityElement.Escape(strTerm) + "</word><match>left</match><relation>=</relation><dataType>string</dataType>" + "<maxCount>" + nMaxResultCount.ToString() + "</maxCount></item>" + "<lang>zh</lang></target>"; } if (string.IsNullOrEmpty(strQueryXml) == true) { List <string> keys = new List <string>(); foreach (string key in notFoundTable.Keys) { keys.Add(key); } strError = $"use '{StringUtil.MakePathList(keys)}' 没有定义"; return(-1); } // 如果有多个props,则需要在检索XML外面包裹一个<target>元素,以作为一个整体和其他部件进行逻辑操作 if (prop_groups.Count > 1) { strQueryXml = "<target>" + strQueryXml + "</target>"; } return(1); } catch (Exception ex) { strError = ex.Message; return(-1); } }