ホットペッパーのWebAPIを使用してHTTPからXML取得、パースするプロシージャ
DBMS_XMLDOMでxmlのパースしてみたかったので
UTL_HTTP使ってWebAPI叩いてXML取得、パースするプロシージャを作ってみました。
ホットペッパーに怒られないか心配ですが(汗
CREATE OR REPLACE PROCEDURE XML_PARSE_TEST IS FUNCTION GET_XML(URL IN VARCHAR2) RETURN DBMS_XMLDOM.DOMDOCUMENT IS REQ UTL_HTTP.REQ; RESP UTL_HTTP.RESP; XML_TEXT CLOB; XML_LINE VARCHAR2(1024); BEGIN REQ := UTL_HTTP.BEGIN_REQUEST( URL=>URL ,METHOD=>'GET' ); UTL_HTTP.SET_BODY_CHARSET( R=>REQ ,CHARSET=>'UTF-8' ); RESP := UTL_HTTP.GET_RESPONSE(R=>REQ); LOOP UTL_HTTP.READ_LINE(RESP, XML_LINE, TRUE); XML_TEXT := XML_TEXT || XML_LINE; END LOOP; UTL_HTTP.END_RESPONSE(RESP); EXCEPTION WHEN UTL_HTTP.END_OF_BODY THEN UTL_HTTP.END_RESPONSE(RESP); RETURN DBMS_XMLDOM.NEWDOMDOCUMENT(XML_TEXT); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(UTL_HTTP.GET_DETAILED_SQLERRM); RETURN NULL; END; FUNCTION GET_NODE_LIST(LIST_NAME IN VARCHAR2,XMLDOC IN DBMS_XMLDOM.DOMDOCUMENT) RETURN DBMS_XMLDOM.DOMNODELIST IS NODELIST DBMS_XMLDOM.DOMNODELIST; BEGIN NODELIST := DBMS_XMLDOM.GETELEMENTSBYTAGNAME( XMLDOC, LIST_NAME ); RETURN NODELIST; END; FUNCTION GET_NODE(NODE_NAME IN VARCHAR2,NODE_LIST IN DBMS_XMLDOM.DOMNODELIST) RETURN DBMS_XMLDOM.DOMNODE IS V_NODE DBMS_XMLDOM.DOMNODE; BEGIN FOR I IN 1..DBMS_XMLDOM.GETLENGTH(NODE_LIST) LOOP V_NODE := DBMS_XMLDOM.ITEM(NODE_LIST, I-1); IF DBMS_XMLDOM.GETNODENAME(V_NODE) = NODE_NAME THEN RETURN DBMS_XMLDOM.GETFIRSTCHILD(V_NODE); END IF; END LOOP; END; FUNCTION GET_NODE_VALUE(NODE_NAME IN VARCHAR2,XMLDOC IN DBMS_XMLDOM.DOMDOCUMENT) RETURN VARCHAR2 IS BEGIN RETURN DBMS_XMLDOM.GETNODEVALUE( GET_NODE( NODE_NAME ,DBMS_XMLDOM.GETCHILDNODES( DBMS_XMLDOM.ITEM( GET_NODE_LIST('Results',XMLDOC) ,0 ) ) ) ); END; PROCEDURE SHOW_SHOPINFO IS XMLDOC DBMS_XMLDOM.DOMDOCUMENT; NODELIST DBMS_XMLDOM.DOMNODELIST; NODE DBMS_XMLDOM.DOMNODE; SHOP_LIST DBMS_XMLDOM.DOMNODELIST; START_COUNT NUMBER; RESULT_COUNT NUMBER; PAGE_PER_COUNT CONSTANT NUMBER := 10; BEGIN XMLDOC := GET_XML('http://api.hotpepper.jp/GourmetSearch/V110/?key=guest&ServiceAreaCD=SA11&Count='||PAGE_PER_COUNT); RESULT_COUNT := GET_NODE_VALUE('NumberOfResults',XMLDOC); DBMS_OUTPUT.PUT_LINE('RESULT_COUNT='||RESULT_COUNT); DBMS_OUTPUT.PUT_LINE('--------------------------------------------------'); -- FOR I IN 0..TRUNC(RESULT_COUNT / PAGE_PER_COUNT) LOOP FOR I IN 0..9 LOOP START_COUNT := (I * PAGE_PER_COUNT) + 1; XMLDOC := GET_XML('http://api.hotpepper.jp/GourmetSearch/V110/?key=guest&ServiceAreaCD=SA11&Count='||PAGE_PER_COUNT||'&Start='||START_COUNT); NODELIST := GET_NODE_LIST('Shop',XMLDOC); FOR I IN 1..DBMS_XMLDOM.GETLENGTH(NODELIST) LOOP NODE := DBMS_XMLDOM.ITEM(NODELIST,I-1); SHOP_LIST := DBMS_XMLDOM.GETCHILDNODES(NODE); DBMS_OUTPUT.PUT_LINE(DBMS_XMLDOM.GETNODEVALUE(GET_NODE('ShopName',SHOP_LIST))); DBMS_OUTPUT.PUT_LINE(DBMS_XMLDOM.GETNODEVALUE(GET_NODE('ShopAddress',SHOP_LIST))); DBMS_OUTPUT.PUT_LINE('--------------------------------------------------'); END LOOP; DBMS_XMLDOM.FREEDOCUMENT(XMLDOC); END LOOP; END; BEGIN SHOW_SHOPINFO; END; /
ACL設定必須です。
あと、DOMDOCUMENTは使用後かならずFREEDOCUMENTで解放してください。
解放しないとメモリをモコモコつかいます。