使用MarkLogic从xdmp:http-get()
或xdmp:http-post()
的网络服务中提取数据,我希望能够检查在我尝试处理数据之前返回的标头。在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()
,但它没有采用任何参数,因此我不知道它正在查看什么响应代码。
答案 0 :(得分:7)
你一下子被两个陷阱烧伤了:
首先,命名空间。 http-get函数的XML输出位于命名空间中,如顶级元素所示:
<response xmlns="xdmp:http-get">
要成功访问该命名空间中的元素,您需要在查询中声明绑定到正确命名空间的前缀,然后在XPath表达式中使用该前缀。例如:
declare namespace h="xdmp:http-get";
//h:code
现在让我们谈谈文档节点。 : - )
您尝试访问$result
,好像它是包含元素的文档节点,但实际上,它是两个根节点的序列(因此它们也不是兄弟节点) 。第一个(您在此处感兴趣的那个)是无父{name}元素 - 而不是包含<response>
元素的文档。
这是一个常见问题:了解文档节点何时存在。文档节点在序列化时始终是不可见的(因此是问题),并且它们始终存在于存储在数据库中的文档中。但是,当您在XQuery中使用裸元素构造函数时(如http-get实现那样),您不构造文档节点,而是构造没有文档节点父节点的元素节点。
例如,以下查询将返回空序列,因为它尝试获取<response>
的{{1}}子项:
<foo>
另一方面,以下 返回<foo>
,因为它获取了文档节点的declare variable $foo := <foo>bar</foo>;
$foo/foo
子节点(必须明确构造) ,在XQuery中):
<foo>
因此,您必须知道给定函数的API是如何设计的(无论它是返回包含元素还是仅包含元素的文档)。
要解决您的问题,请不要尝试访问<foo>
(正试图获取$declare variable $doc := document{ <foo>bar</foo> };
$doc/foo
$result/h:response/h:code
的孩子。相反,请访问<response>
(或更准确地说<response>
,因为$result/h:code
是http-get函数返回的两个节点序列中的第一个。
有关文档节点的更多信息,请查看此博客文章系列:http://community.marklogic.com/blog/document-formats-part1