Xquery 从xdmp:HTTP-get()访问HTTP响应

Xquery 从xdmp:HTTP-get()访问HTTP响应,xquery,marklogic,Xquery,Marklogic,使用MarkLogic从带有xdmp:http-get()或xdmp:http-post()的web服务中提取数据,我希望能够在尝试处理数据之前检查返回的头。在DQ中,我可以这样做: let $result := xdmp:http-get($query,$options) (: $query and $options are fine, I promise. :) return $result 我得到的结果如下: <v:results v:warning="more than one

使用MarkLogic从带有
xdmp:http-get()
xdmp:http-post()
的web服务中提取数据,我希望能够在尝试处理数据之前检查返回的头。在DQ中,我可以这样做:

let $result := xdmp:http-get($query,$options) (: $query and $options are fine, I promise. :)
return $result
我得到的结果如下:

<v:results v:warning="more than one node">
       <response>
           <code>200</code>
            <message>OK</message>
            <headers>
              <server>(actual server data was here)</server>
              <date>Thu, 07 Jun 2012 16:53:24 GMT</date>
              <content-type>application/xml;charset=UTF-8</content-type>
              <content-length>2296</content-length>
              <connection>close</connection>
            </headers>
        </response>
然后是实际响应。问题是我似乎无法通过XPath访问这个响应节点。如果我将return语句更改为
return$result/response/code
,则得到空序列。如果我可以在处理返回的实际数据之前检查代码以确保返回的数据是200,那么比使用try-catch块查看数据是否存在并且是否正常要好得多

因此,如果有人知道如何访问这些响应代码,我希望看到您的解决方案


作为记录,我尝试了
xdmp:get-response-code()
,但它不接受任何参数,所以我不知道它在看什么样的响应代码。

您同时被两个gotchas烧坏了:

  • 名称空间意识
  • 文档节点的感知
首先,名称空间。http get函数的XML输出位于顶级元素看到的命名空间中:

<response xmlns="xdmp:http-get">
现在让我们谈谈文档节点。:-)

您试图访问
$result
,就好像它是一个包含元素的文档节点,但实际上,它是一个由两个根节点组成的序列(因此它们也不是兄弟节点)。第一个元素(您在这里感兴趣的元素)是无父元素的
元素,而不是包含
元素的文档

这是一个常见的问题:知道文档节点是否存在。文档节点在序列化时总是不可见的(因此是gotcha),并且它们总是出现在存储在数据库中的文档上。但是,当您在XQuery中仅使用裸元素构造函数时(正如http get实现所做的那样),您构造的不是文档节点,而是没有文档节点父节点的元素节点

例如,以下查询将返回空序列,因为它试图获取
子项:

声明变量$foo:=bar;
$foo/foo
另一方面,以下内容确实返回
,因为它获取文档节点的
子节点(在XQuery中必须显式构造):

$declare变量$doc:=document{bar};
$doc/foo
因此,您必须知道给定函数的API是如何设计的(它是返回包含元素的文档还是只返回元素)

要解决您的问题,请不要尝试访问
$result/h:response/h:code
(它正在尝试获取
的子级)。相反,访问
$result/h:code
(或者更准确地说是
$result[1]/h:code
,因为
是http get函数返回的两个节点序列的第一个)


有关文档节点的更多信息,请查看本博客文章系列:

关于名称空间,我有时会作弊(特别是当像
这样没有存储在数据库中的短暂XML没有实际性能影响时),与其声明名称空间,不如使用名称空间通配符:
$result/*:code
declare namespace h="xdmp:http-get";
//h:code
declare variable $foo := <foo>bar</foo>;
$foo/foo
$declare variable $doc := document{ <foo>bar</foo> };
$doc/foo