dp2library API 大全 - DigitalPlatform/dp2 GitHub Wiki
先用 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 属性值就组成了全部检索点的统一名称集合。
然后用 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"。
先用 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 的读者库名参数那里使用 “<全部>”。