2013-06-20 110 views
0

我正在嘗試從plsql調用webservice。我有以下代碼(工作):使用plsql調用rss feed

CREATE OR REPLACE PROCEDURE WEBSERVICE AS 
    v_xml XMLTYPE; 
BEGIN 
    v_xml := XMLTYPE(UTL_HTTP.REQUEST(URL => 'http://dev.markitondemand.com/Api/Quote?symbol=AAPL')); 
    FOR x IN (SELECT 
     EXTRACTVALUE(VALUE(p), '/Data/Status/text()') AS title 
    FROM TABLE(XMLSEQUENCE(EXTRACT(v_xml, '/QuoteApiModel/Data'))) p) 
    LOOP 
     DBMS_OUTPUT.PUT_LINE(x.title); 
    END LOOP; 
    COMMIT; 
END; 

但是這個代碼不工作:

CREATE OR REPLACE PROCEDURE WEBSERVICE AS 
    v_xml XMLTYPE; 
BEGIN 
    v_xml := XMLTYPE(UTL_HTTP.REQUEST(URL => 'http://xkcd.com/rss.xml')); 
    FOR x IN (SELECT 
     EXTRACTVALUE(VALUE(p), 'item/title/text()') AS title 
    FROM TABLE(XMLSEQUENCE(EXTRACT(v_xml, '/rss/channel/item'))) p) 
    LOOP 
     DBMS_OUTPUT.PUT_LINE(x.title); 
    END LOOP; 
    COMMIT; 
END; 

它給了我下面的錯誤:

Connecting to the database oracle. 
ORA-31011: XML parsing failed 
ORA-19202: Error occurred in XML processing 
LPX-00007: unexpected end-of-file encountered 
ORA-06512: at "SYS.XMLTYPE", line 310 
ORA-06512: at "SYS.WEBSERVICE", line 4 
ORA-06512: at line 2 
Process exited. 
Disconnecting from the database oracle. 

我注意到不同的是xkcd rss feed有一個xml頭,另一個沒有。我應該怎麼做才能做到這一點?

回答

0

你說得對,因爲XML頭的存在而發生錯誤。

解決方法是使用XMLParse(document ...)解析XML:

select xmlparse(document UTL_HTTP.REQUEST(URL => 'http://xkcd.com/rss.xml')) 
into v_xml 
from dual; 

Example SQLFiddle與xkcd.com結果。

注意,根據documentationHTTP_UTIL.Request函數只返回2000字節的服務器響應,所以你可以得到不完整的XML與這樣的請求。

更新

更優雅的方式從XML是使用XMLTable()函數XQuery提取值:

FOR x IN (

    select title 
    from 
    XMLTable(
     'for $i in $p/rss/channel/item/title return $i' 
     passing 
     XMLParse(document UTL_HTTP.REQUEST(URL => '...')) as "p" 
     columns 
     title varchar2(4000) path '//title' 
    ) 

) 
LOOP 
    DBMS_OUTPUT.PUT_LINE(x.title); 
END LOOP; 

SQLFiddle

至少,這種方法可以讓你創建更靈活不同來源的RSS選項。