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

Nat*_*teD 2 xquery marklogic

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

let $result := xdmp:http-get($query,$options) (: $query and $options are fine, I promise. :)
return $result
Run Code Online (Sandbox Code Playgroud)

我得到的结果看起来像这样:

<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>
Run Code Online (Sandbox Code Playgroud)

然后是实际的回应.问题是我似乎无法将XPath放入此响应节点.如果我改变我的return语句,return $result/response/code我得到空序列.如果我可以检查该代码以确保在尝试处理返回的实际数据之前得到200,那么使用try-catch块来查看数据是否存在且是否合理要好得多.

所以,如果有人知道如何访问这些响应代码,我很乐意看到你的解决方案.

为了记录,我尝试过xdmp:get-response-code(),但它没有采取任何参数,所以我不知道它正在看什么响应代码.

Eva*_*enz 7

你一下子被两个陷阱焚烧了:

  • 对名称空间的认识
  • 意识到文档节点

首先是命名空间.http-get函数的XML输出位于命名空间中,如顶级元素所示:

<response xmlns="xdmp:http-get">
Run Code Online (Sandbox Code Playgroud)

要成功访问该命名空间中的元素,您需要在查询中声明绑定到正确命名空间的前缀,然后在XPath表达式中使用该前缀.例如:

declare namespace h="xdmp:http-get";
//h:code
Run Code Online (Sandbox Code Playgroud)

现在让我们谈谈文档节点.:-)

您尝试访问$result就像它是包含元素的文档节点一样,但实际上,它是两个根节点的序列(因此它们也不是兄弟节点).第一个(你在这里感兴趣的那个)是一个无父<response>元素 - 而不是包含<response>元素的文档.

这是一个常见问题:了解文档节点何时存在.文档节点在序列化时始终是不可见的(因此是陷阱),并且它们始终存在于存储在数据库中的文档中.但是,当您在XQuery中使用裸元素构造函数时(如http-get实现那样),您构造的不是文档节点,而是构造没有文档节点父节点的元素节点.

例如,以下查询将返回空序列,因为它正在尝试获取以下<foo>子项<foo>:

declare variable $foo := <foo>bar</foo>;
$foo/foo
Run Code Online (Sandbox Code Playgroud)

另一方面,下面的确会返回<foo>,因为它正在获取<foo>文档节点的子节点(必须在XQuery中显式构造):

$declare variable $doc := document{ <foo>bar</foo> };
$doc/foo
Run Code Online (Sandbox Code Playgroud)

因此,您必须知道给定函数的API是如何设计的(无论它返回包含元素还是仅包含元素的文档).

要解决您的问题,请不要尝试访问$result/h:response/h:code(这是试图让<response>孩子的<response>).相反,访问$result/h:code(或更确切地说$result[1]/h:code,因为<response>是http-get函数返回的两个节点序列中的第一个).

有关文档节点的更多信息,请查看此博客文章系列:http://community.marklogic.com/blog/document-formats-part1

  • 在命名空间上,我有时会作弊(特别是当没有真正的性能影响时,如短暂的XML,如`<response>`,它没有存储在数据库中)而不是声明命名空间,只需使用命名空间通配符:`$ result/*:code` (3认同)