dp2library API 大全 - DigitalPlatform/dp2 GitHub Wiki

目录:

SearchBiblio() -- 检索书目库

检索书目库

先用 API SearchBiblio() 进行检索,获得一个结果集

                long lRet = Channel.SearchBiblio(stop,
strBiblioDbName,  // 书目库名。可以是单个的书目库名,也可以是多个书目库名(逗号间隔)。还可以用 "<all>" 表示全部书目库
"中国",             // 检索词
-1,             // 最大命中数。-1 表示不做限制
"recid",    // 检索途径的统一名称
"left",         // 匹配方式
"zh",           // 语种
"default",   // 结果集名
"", // strSearchStyle 检索风格
"", // strOutputStyle 输出风格
out strError);

若返回 -1 表示检索过程出错。若返回 0 则表示没有任何命中结果。返回其他值表示命中记录条数。SearchBiblio() API 并不能直接获得命中的记录信息,只能通过函数返回值得知命中的记录条数。命中结果被放入指定的结果集。要获得结果集内的记录,需要调用 API GetSearchResult() (一次或多次)获得结果集中的命中记录。参见本文中关于 GetSearchResult() 的介绍。

参数“检索词的统一名称”,可以在书目库的 keys 配置文件中查到。也可以在内务前端的书目查询窗的“检索途径”下拉列表中看到,是这个列表每行右端的那个英文名称。注意不是列表左端的汉字名称。

这里是 keys 配置文件的一个片段:

......
  <table name="title" id="2" type="title">
    <convert>
      <string style="upper,stopword,simplify" stopwordTable="title" />
    </convert>
    <convertquery>
      <string style="upper,stopword,simplify" stopwordTable="title" />
    </convertquery>
    <caption lang="zh-CN">题名</caption>
    <caption lang="en">Title</caption>
  </table>
......

注意其中 table 元素的 type 属性值 "title" 就是题名这个检索途径的统一名称。统一的意思是,无论是中文图书库(UNIMARC格式),还是英文图书库(MARC21格式),题名都可以用 "title" 来指称,对于针对统一类型检索点的跨库检索的来说,使用统一检索点名称非常必要。keys 配置文件中的所有 table 元素的 type 属性值就组成了全部检索点的统一名称集合。

GetSearchResult() -- 获得结果集内的记录

然后用 API GetSearchResult() 获得结果集中的命中记录。

                long lHitCount = lRet;

                long lStart = 0;
                long lCount = lHitCount;
                DigitalPlatform.LibraryClient.localhost.Record[] searchresults = null;

                for (; ; )
                {
                    lRet = Channel.GetSearchResult(
                        stop,
                        "default",   // 结果集名
                        lStart,         // 起点偏移
                        lCount,         // 本次希望获取的记录条数
                        "id,cols",      // 格式。此例希望获取的格式为:第一列记录路径(包含 ID),其余的列是浏览列(由数据库的 browse 配置文件定义)
                        "zh",
                        out searchresults,
                        out strError);
                    if (lRet == -1 || lRet == 0)
                        return -1;

                    // 此时 searchresults 数组里面就是返回的命中记录。处理它们。

                    lStart += searchresults.Length;
                    lCount -= searchresults.Length;
                    if (lStart >= lHitCount || lCount <= 0)
                        break;
                }

这是一个循环,每次 API 调用获取若干记录,直到结果集中的记录全部获取完。

如果希望获取到每条记录的 XML 内容,可以在格式参数中包含 "xml"。例如 "id,cols,xml"。希望获得时间戳,可以在格式参数中包含 "timestamp"。

SearchReader() -- 检索读者库

检索和获得读者指纹信息

先用 API SearchReader() 进行检索,获得一个结果集

                long lRet = Channel.SearchReader(stop,
strReaderDbName,  // 读者库名。可以是单个的读者库名,也可以是多个读者库名(逗号间隔)
"",             // 检索词
-1,             // 最大命中数
"指纹时间戳",    // 检索途径名称
"left",         // 匹配方式
"zh",           // 语种
"resultset1",   // 结果集名
"", // strOutputStyle
out strError);

若返回 -1 表示检索过程出错。若返回 0 则表示没有任何命中结果。返回其他值表示命中记录条数。

然后用 API GetSearchResult() 获得结果集中的命中记录。

                long lHitCount = lRet;

                long lStart = 0;
                long lCount = lHitCount;
                DigitalPlatform.LibraryClient.localhost.Record[] searchresults = null;

                for (; ; )
                {
                    lRet = Channel.GetSearchResult(
                        stop,
                        "resultset1",   // 结果集名
                        lStart,         // 起点偏移
                        lCount,         // 本次希望获取的记录条数
                        "id,cols,format:cfgs/browse_fingerprint"
                        "zh",
                        out searchresults,
                        out strError);
                    if (lRet == -1 || lRet == 0)
                        return -1;

                    // 此时 searchresults 数组里面就是返回的命中记录。处理它们。

                    lStart += searchresults.Length;
                    lCount -= searchresults.Length;
                    if (lStart >= lHitCount || lCount <= 0)
                        break;
                }

这是一个循环,每次 API 调用获取若干记录,直到结果集中的记录全部获取完。

读者库的 browse_fingerprint 配置文件内容列在这里,便于参考:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <col title="指纹时间戳">
    <xpath>*/fingerprint/@timestamp</xpath>
  </col>
  <col title="证条码号">
    <xpath>*/barcode</xpath>
  </col>
  <col title="指纹数据">
    <xpath>*/fingerprint</xpath>
  </col>
</root>

可以看出,检索命中的结果如用上述格式返回,一个记录一共包含 3 列,分别是 指纹时间戳,证条码号,指纹数据。

如何获得当前用户可以操作的读者库名?

上面代码示范了如何根据一个读者库名,去获得这个读者库中的全部指纹信息。那如何获得当前用户可以操作的读者库名呢?

下面代码示范了,用 GetSystemParameter() API 去获得读者库定义 XML。

            string strValue = "";
            long lRet = Channel.GetSystemParameter(stop,
    "system",
    "readerDbGroup",
    out strValue,
    out strError);
            if (lRet == -1)
                return -1;

所返回的 XML 内容在 strValue 中。注意这是一个不完整的 XML 片段,可以用下面代码装入一个 XmlDocument 对象:

            XmlDocument dom = new XmlDocument();
            dom.LoadXml("<root />");

            try
            {
                dom.DocumentElement.InnerXml = strValue;
            }
            catch (Exception ex)
            {
                strError = "category=system,name=readerDbGroup所返回的XML片段在装入InnerXml时出错: " + ex.Message;
                return -1;
            }

然后解析这个 XML 结构,把每个 database 元素的 name 属性提取出来,就是 dp2library 全部读者库名。但需要注意的是,当前用户不一定对每个读者库都有操作权限。需要同时提取出 database 元素的 libraryCode 属性,然后和最开始调用 Login() API 时候返回的 strLibraryCode (即单当前用户所在的分馆列表,逗号分隔的字符串)进行对比,过滤掉当前用户不能操作的那些分馆代码的 database 元素(及其 name 属性)。

可参考以下代码:

            string strLibraryCodeList = this.Channel.LibraryCodeList;   // 从 Login() API 获得的当前用户管辖的馆代码列表

            XmlNodeList nodes = dom.DocumentElement.SelectNodes("database");
            foreach (XmlElement node in nodes)
            {
                string strLibraryCode = node.GetAttribute("libraryCode");

                if (Global.IsGlobalUser(strLibraryCodeList) == false)
                {
                    if (StringUtil.IsInList(strLibraryCode, strLibraryCodeList) == false)  // 检测 strLibraryCode 内容是否包含在 strLibraCodeList 的内容列表字符串中
                        continue;
                }

                string strDbName = node.GetAttribute("name");
                readerdbnames.Add(strDbName);
            }

除了用这里介绍的办法,去获得一个一个的读者库名,以外,还有一个方法就是在 SearchReader() API 的读者库名参数那里使用 “<全部>”。

⚠️ **GitHub.com Fallback** ⚠️