2012-04-15 54 views
1

我想從twitter獲取XML feed,使用marklogic XDMP API,我能夠在Xquery控制檯中獲取XML,但無法弄清楚如何轉換該xml以及放入命名數據庫。我做如下:xmdp:http-get和xdmp:insert-document

  1. 當打這個網址「http://search.twitter.com/search.atom?q=pankaj&since_id=1212121」使用xdmp:http-get功能我獲得以下XML:

    <?xml version="1.0" encoding="UTF-8"?> 
        <twitter> 
        <entry> 
         <id>1212121</id> 
         <content>did u hear what he talked about Pankaj</content> 
        </entry> 
        <entry> 
        <id>1212122</id> 
         <content>abc xyz abc xyz</content> 
        </entry> 
    </twitter> 
    
  2. 現在我想這個XML分割成每<entry>文件並插入到marklogic數據庫。

  3. 此外,該腳本應該每30秒安排一次,下一次應該在URL中的since_id字段中附加最後一個條目的ID。

我嘗試以下,但收到的一些錯誤,也不知從哪裏給DB名稱,以及如何追加since_id

let $content := xdmp:http-get("http://search.twitter.com/search.atom?q=pankaj&since_id=191622916163641344", 
<options xmlns="xdmp:document-get"> 
    <encoding>UTF-8</encoding> 
</options>) 
return 
for $i in $content//entry 
return 
xdmp:document-insert(
    "/example.xml", $content//entry, 
    xdmp:default-permissions(), 
    xdmp:default-collections(), 
10) 

回答

0

請參閱xdmp:http-get的參考手冊頁。 xdmp:http-get返回一系列的項目。

從參考手冊:

在xdmp的輸出的第一節點:HTTP-GET是響應頭 從HTTP服務器。

xdmp:http-get輸出中的第二個節點是來自 http服務器的響應。響應被視爲文本,XML或二進制文件,取決於從http服務器發送的內容類型頭文件。如果 節點爲html,則標頭應指示文本/ html,默認情況下該文本將作爲文本文檔返回 。文檔類型由 確定mimetypes映射,並且您可以根據需要更改Admin接口中的映射。如果您碰巧知道響應是XML,即使頭沒有將其指定爲XML,並且想要將XML響應處理爲 ,您也可以將響應包裝爲xdmp:unquote調用,並將其解析爲 XML。您也可以使用xml 選項(在xdmp:document-get命名空間中)告訴API將文檔視爲XML。此外,如果您知道響應是HTML 文檔,則可以將響應封裝在xdmp:tidy調用中, 將文本視爲HTML,將其清理並返回一個XHTML XML文檔。

您應該檢查第一項中的響應類型和狀態。如果它是一個文本/ XML響應,那麼你可以做

for $i in $content[2]//entry 

得到的東西,每30秒運行,您可以使用計劃任務。如果您只想存儲新文檔,則可以通過Twitter爲每條推文提供的唯一Twitter網址/ ID存儲每個文檔。您還可以將最後一個'id'存儲在數據庫中的文檔中,然後在每次運行fetcher時拔出並更新它。

3

一個錯誤可能是關於未轉義的&符號的投訴,它在XQuery(如XML)中需要使用&amp;進行轉義。

您還需要聲明Atom命名空間,因爲從Twitter返回的內容將其用作其默認命名空間。

您還需要爲每個文檔指定一個唯一的名稱;否則,MarkLogic會拋出CONFLICTINGUPDATES錯誤。在下面的解決方案中,我在結果文檔的URI中使用推文ID(從<atom:id>元素中解析它)。

要更新since_id值,您有幾個選項。不幸的是,來自Twitter的XML不包括原始推特ID作爲其元素或屬性的自己的值,這意味着如果不在插入時首先修改文檔就不能創建範圍索引(以包括諸如一個領域)。但是我們可以利用這個事實,即我們在URI中使用推特ID。啓用URI詞典(管理界面中的全局數據庫選項)將允許您撥打cts:uris()輕鬆獲取您存儲的最新推文ID。

這是我想出了使用該技術的完整的解決方案:

declare namespace atom="http://www.w3.org/2005/Atom"; 
declare variable $initial-tweet-id := "191622916163641344"; 
declare variable $uri-prefix := "/tweets/"; 
declare variable $uri-suffix := ".xml"; 
declare variable $latest-tweet-uri := cts:uri-match(concat($uri-prefix,"*"))[last()]; 
declare variable $latest-tweet-id := if ($latest-tweet-uri) 
            then substring-after(
              substring-before($latest-tweet-uri,$uri-suffix), 
              $uri-prefix) 
            else $initial-tweet-id; 


let $content := xdmp:http-get(
        concat("http://search.twitter.com/search.atom?q=pankaj&amp;since_id=", 
         $latest-tweet-id), 
<options xmlns="xdmp:document-get"> 
    <encoding>UTF-8</encoding> 
</options>) 
for $entry in $content//atom:entry 
let $tweet-id := tokenize($entry/atom:id, ":")[last()] 
return 
    (xdmp:log(concat("Adding tweet:", $tweet-id)), 
    xdmp:document-insert(
    concat($uri-prefix, $tweet-id, $uri-suffix), 
    $entry, 
    xdmp:default-permissions(), 
    xdmp:default-collections(), 
    10) 
) 

要運行這個每隔30秒,你可以使用管理界面來設置計劃任務(配置 - >組 - >默認 - >計劃任務)。這也是你指定要運行它的數據庫的地方。 (在查詢控制檯,你只需要使用「內容源」的下拉菜單。)

替代方法:

  • 插入上負載存儲該鳴叫ID的元素,然後使用一系列索引上以查找最高價值。
  • <atom:published>上創建日期時間範圍索引,使用該索引查找最新的推文,並從<atom:id>值中提取推文ID。

我的解決方案和上述兩個替代方案中的第一個不需要任何磁盤讀取,所以它們在這方面是可取的。

+0

謝謝你的幫助。這個腳本對我來說是完美的。 – Pankaj 2012-04-16 17:49:29