首页 > 解决方案 > Xquery递归查询不设置变量

问题描述

[编辑更完整的成功与错误示例]

在 Xquery 3(eXist 4.7)中,我正在使用一个公共 API(Zotero),它使用这个 GET 请求提供一个书目列表:https ://api.zotero.org/groups/2304628/items?format=atom&content=tei&v=3

提供者将响应分成 25 个项目,每个响应(预期为 3202,如第一个响应中所示),因此我必须使用参数在循环中获取下一个 25、25、25...。API 响应有助于提供带有参数的完整 URL 以发出下一个请求:

 <link rel="self" type="application/atom+xml"
            href="https://api.zotero.org/groups/2304628/items?content=tei&amp;format=atom"/>
 <link rel="next" type="application/atom+xml"
            href="https://api.zotero.org/groups/2304628/items?content=tei&amp;format=atom&amp;start=25"/>
 <link rel="last" type="application/atom+xml"
            href="https://api.zotero.org/groups/2304628/items?content=tei&amp;format=atom&amp;start=3200"/>

我正在尝试构建一个查询,该查询以递归方式发送nextURL 的 GET,并且每个“递归”检查是否$current-url$last-url. 当它们匹配时,结束递归。

以下产生错误err:XPDY0002 variable '$next-url' is not set

xquery version "3.1";

module namespace zotero="/db/apps/thema/modules/zotero";
declare namespace tei="http://www.tei-c.org/ns/1.0";
declare namespace atom = "http://www.w3.org/2005/Atom";

declare function zotero:get-recursive($current-url as xs:string)
{
  let $APIdoc := httpclient:get($current-url,true(),<headers/>)
  let $next-url := $APIdoc//atom:link[@rel="next"]/data(@href)
  let $last-url := $APIdoc//atom:link[@rel="last"]/data(@href)

  (: perform db insert from API data:)
  let $bibdoc := doc("db/apps/myapp/data/list_bibliography.xml")
  let $insert-doc := for $content in $APIdoc//atom:content
                let $x := parse-xml($content/text())
                return update insert $x//tei:biblStruct into $bibdoc//tei:listBibl

  return 
        if ($current-url = $last-url)
            then "finished"
            else zotero:get-recursive($next-url)         
};

删除递归函数成功插入数据并返回正确的next-url

xquery 版本“3.1”;

module namespace zotero="/db/apps/thema/modules/zotero";
declare namespace tei="http://www.tei-c.org/ns/1.0";
declare namespace atom = "http://www.w3.org/2005/Atom";

declare function zotero:get-recursive($current-url as xs:string)
{
  let $APIdoc := httpclient:get($current-url,true(),<headers/>)
  let $next-url := $APIdoc//atom:link[@rel="next"]/data(@href)
  let $last-url := $APIdoc//atom:link[@rel="last"]/data(@href)

  let $bibdoc := doc("db/apps/myapp/data/list_bibliography.xml")
  let $insert-doc := for $content in $APIdoc//atom:content
                let $x := parse-xml($content/text())
                return update insert $x//tei:biblStruct into $bibdoc//tei:listBibl 
  return ($insert-doc, $next-url)
};

xquery 递归中是否存在干扰变量设置/使用的内容?还是我完全错误地接近这个?

非常感谢。

标签: xqueryexist-db

解决方案


我会切换到不同的 http-client:http ://expath.org/modules/http-client/

这个是社区推荐使用的,因为存在版本 4.1+。


declare function zotero:get-recursive($current-url as xs:string)
{
  let $response := http:send-request(<http:request href="{$current-url}" method="get" />)
  (: try catch or other error handling would be good here :)
  (: assuming status 200 :)
  let $APIdoc := $response[2]
  let $next-url := $APIdoc//atom:link[@rel="next"]/data(@href)
  let $last-url := $APIdoc//atom:link[@rel="last"]/data(@href)

  (: perform db insert from API data:)
  let $bibdoc := doc("db/apps/myapp/data/list_bibliography.xml")
  let $insert-doc := for $content in $APIdoc//atom:content
                let $x := parse-xml($content/text())
                return update insert $x//tei:biblStruct into $bibdoc//tei:listBibl

  return 
        if ($current-url = $last-url)
            then "finished"
            else zotero:get-recursive($next-url)         
};

推荐阅读