2012-06-07 90 views
2

使用MarkLogic從網絡服務中提取xdmp:http-get()xdmp:http-post()的數據,我希望能夠檢查返回的標題,然後再嘗試處理數據。在DQ我可以這樣做:訪問來自xdmp的HTTP響應:http-get()

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 $result/response/code,我會得到空序列。如果我可以檢查該代碼以確保在嘗試處理返回的實際數據之前返回200,那麼它將比使用try-catch塊來查看數據是否存在並且是否理智更好。

因此,如果有人知道如何訪問這些響應代碼,我很樂意看到您的解決方案。

爲了記錄,我試過xdmp:get-response-code(),但它不需要任何參數,所以我不知道它在查看什麼響應代碼。

回答

7

你得到兩個陷阱一次燒:

  • 命名空間的意識
  • 文檔節點的意識

首先,命名空間。在HTTP-GET功能的XML輸出是一個命名空間由頂級元素所見:

<response xmlns="xdmp:http-get"> 

成功訪問的元素在命名空間中,你需要聲明綁定到正確的查詢前綴名稱空間,然後在XPath表達式中使用該前綴。例如:

declare namespace h="xdmp:http-get"; 
//h:code 

現在我們來談談文檔節點。 :-)

您試圖訪問$result就好像它是一個包含元素的文檔節點,但實際上它是由兩個根節點組成的序列(因此它們不是兄弟)。第一個(你在這裏感興趣的)是一個無父母的<response>元素 - 而不是一個包含<response>元素的文檔。

這是一個常見的問題:知道文檔節點是否存在。文檔節點在序列化時始終是不可見的(因此存在),並且它們始終存在於存儲在數據庫中的文檔中。但是,當您僅在XQuery中使用裸元素構造函數(如http-get實現那樣)時,不會構建文檔節點,而會構造沒有文檔節點父元素的元素節點。

例如,下面的查詢將返回空序列,因爲它試圖讓<foo>孩子的<foo>

declare variable $foo := <foo>bar</foo>; 
$foo/foo 

在另一方面,下面的確實返回<foo>,因爲它是越來越所述<foo>子文檔節點(其必須被顯式構造,在XQuery中):

$declare variable $doc := document{ <foo>bar</foo> }; 
$doc/foo 

所以你必須知道給定函數的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

+3

在命名空間,我有時會欺騙(尤其是當有沒有真正的性能問題與短暫的XML一樣未存儲在''數據庫),而不是聲明一個名稱空間,只需使用一個名稱空間通配符:'$ result/*:code' –