コード例 #1
0
ファイル: Z3950Utility.cs プロジェクト: cobbybyent/chord
        // 构造一个检索词的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);
            }
        }
コード例 #2
0
        // 构造一个检索词的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);
            }
        }