Mac De PL/SQL RSS Reader #4 Tweet
前回のつづきです。
前回までで文字化けを回避できることが確認できたので、本題RSSリーダーの元ネタで試してみることにする。
尚、オリジナルになるべく近い形にしてある。(対象は、megawattさんのRSS 0.91フォーマット)
まずは、結果から。(いつものように、Oracle SQL Developer 1.0 for MacOSXを使ってます)
データベースOracle10g R1 grasscatfishに接続中です。
begin...
====================
メガ放談 - most recent 15 articles:
====================
TITLE: ギザ耳は地域猫の証し
URL : http://megawatt.blogdns.net/blog/254
—————————————-
TITLE: 亀田家親子夏休み日記
URL : http://megawatt.blogdns.net/blog/253
—————————————-
TITLE: 社会保険事務所に行ってきた
URL : http://megawatt.blogdns.net/blog/252
—————————————-
TITLE: 重なるときは重なる Part2
URL : http://megawatt.blogdns.net/blog/251
—————————————-
TITLE: 重なるときは重なる
URL : http://megawatt.blogdns.net/blog/250
—————————————-
TITLE: うしろすがた
URL : http://megawatt.blogdns.net/blog/249
—————————————-
TITLE: 猫のための写真講座/2006年度前期・4
URL : http://megawatt.blogdns.net/blog/248
—————————————-
TITLE: ワイン100mlが80キロカロリー!!
URL : http://megawatt.blogdns.net/blog/247
—————————————-
TITLE: はっちゃんではないはっちゃん
URL : http://megawatt.blogdns.net/blog/246
—————————————-
TITLE: ちょっと、走ってる
URL : http://megawatt.blogdns.net/blog/245
—————————————-
TITLE: 命名、じみへん
URL : http://megawatt.blogdns.net/blog/244
—————————————-
TITLE: 猫まんが at門前仲町
URL : http://megawatt.blogdns.net/blog/243
—————————————-
TITLE: 猫を拾った日
URL : http://megawatt.blogdns.net/blog/242
—————————————-
TITLE: お飲物なににしますか?
URL : http://megawatt.blogdns.net/blog/241
—————————————-
TITLE: 門前仲町・深川不動堂
URL : http://megawatt.blogdns.net/blog/240
—————————————-
...End
プロセス終了。
データベースOracle10g R1 glasscatfishから切断中です。
以下、プロシージャのソース。
比較し易いように、オリジナルのソースになるべく近い形式にしてある。
CREATE OR REPLACE PROCEDURE RSS_FEED_READER
(
i_url IN VARCHAR2
)
AS
--============ TYPEs/VARIABLEs ===============================================
TYPE rss_type IS RECORD
(
title VARCHAR2(2000),
link VARCHAR2(200),
pubDate VARCHAR2(200),
category VARCHAR2(500),
description VARCHAR2(4000)
);
v_rss_item rss_type;
v_rss_empty_item rss_type; -- v_rss_item初期化用
v_url VARCHAR2(32767);
-- XML PARSER
v_myParser DBMS_XMLPARSER.Parser;
-- RSSまたは、ATOMフォーマットのDOM
v_rssDoc DBMS_XMLDOM.DomDocument;
v_itemNode DBMS_XMLDOM.DomNode;
v_childnode DBMS_XMLDOM.DomNode;
v_rssEntryList DBMS_XMLDOM.DomNodeList;
v_rssItemFields DBMS_XMLDOM.DomNodeList;
v_childNodeText VARCHAR2(32767);
-- for UTL_HTTP
v_req UTL_HTTP.REQ;
v_resp UTL_HTTP.RESP;
-- HTTP経由でRSS/ATOMソースを取り込むためのワーク
v_source VARCHAR2(1024);
v_tempSourceClob CLOB;
-- RSS/ATOMをXMLTYPEで扱うためのワーク
v_tempXMLTYPE XMLTYPE;
--========== Internal PROCEDUREs/FUNCTIONs ===================================
--
--****************************************************************************
--* VARCHAR2の文字列を最大で255文字または、改行コード毎にプリントする内部プロシージャ
--*
--* NOTE:
--* Oracle10g R2では、DBMS_OUTPUT.PUT_LINEプロシージャの255文字制限がないため、
--* 255文字毎に分割出力する必要はなくなる
--****************************************************************************
PROCEDURE println
(
i_text IN VARCHAR2
)
IS
v_src VARCHAR2(32767);
v_tempStr VARCHAR2(32767);
BEGIN
v_src := i_text;
IF INSTR(v_src, UTL_TCP.CRLF) <> 0 THEN
v_tempStr := SUBSTR(v_src, 1, INSTR(v_src, UTL_TCP.CRLF)-1);
v_src := SUBSTR(v_src, INSTR(v_src, UTL_TCP.CRLF)+LENGTH(UTL_TCP.CRLF));
ELSE
v_tempStr := v_src;
END IF;
WHILE v_tempStr IS NOT NULL LOOP
IF LENGTH(v_tempStr)> 255 THEN
FOR i IN 1..(TRUNC(LENGTH(v_tempStr)/255)+1) LOOP
DBMS_OUTPUT.PUT_LINE(SUBSTR(v_tempStr,1+ 255*(i-1),255));
END LOOP;
ELSE
DBMS_OUTPUT.PUT_LINE(v_tempStr);
END IF;
IF INSTR(v_src, UTL_TCP.CRLF) <> 0 THEN
v_tempStr := SUBSTR(v_src, 1, INSTR(v_src, UTL_TCP.CRLF)-1);
v_src := SUBSTR(v_src, INSTR(v_src, UTL_TCP.CRLF)+LENGTH(UTL_TCP.CRLF));
ELSE
EXIT;
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error Occured : println(VARCHAR2) internal procedure.');
DBMS_OUTPUT.PUT_LINE(sqlerrm());
RAISE;
END println;
PROCEDURE report_rss_item(p_rss_item IN rss_type)
IS
BEGIN
println('TITLE: '||p_rss_item.title);
println('URL : '||p_rss_item.link);
IF p_rss_item.pubDate IS NOT NULL THEN
println('Published on: '||p_rss_item.pubDate);
END IF;
IF p_rss_item.category IS NOT NULL THEN
println('Category: '||p_rss_item.category);
END IF;
IF p_rss_item.description IS NOT NULL THEN
println('==');
println('Summary: '||p_rss_item.description);
END IF;
println('—————————————-');
println(' ');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error occured : report_rss_item internal procedure');
DBMS_OUTPUT.PUT_LINE(sqlerrm());
RAISE;
END report_rss_item;
--****************************************************************************
--* Main procedure
--****************************************************************************
BEGIN
DBMS_OUTPUT.ENABLE(200000);
println('begin...');
v_url := i_url;
IF v_url IS NULL THEN
RAISE_APPLICATION_ERROR(-20000, 'URLを指定してください。');
END IF;
v_req := UTL_HTTP.BEGIN_REQUEST(v_url);
UTL_HTTP.SET_HEADER(v_req, 'User-Agent', 'Oracle UTL_HTTP/Oracle10g R1');
UTL_HTTP.SET_HEADER(v_req, 'Content-Type', 'text/xml;charset=UTF-8');
v_resp := UTL_HTTP.GET_RESPONSE(v_req);
-- RSSソースを一時CLOBへ書き出す
DBMS_LOB.CREATETEMPORARY(v_tempSourceClob, FALSE);
BEGIN
LOOP
UTL_HTTP.READ_LINE(v_resp, v_source, true);
-- 改行コード強制的に付加。
-- xml_println()でDBMS_OUTPUT.PUT_LINE()が、最大255文字までしか
-- 表示できないことへの一時的な対策。(試しているサイトについてはこれで
-- 回避できているので今のところはこのままで。)
v_source := v_source || UTL_TCP.CRLF;
DBMS_LOB.WRITEAPPEND(v_tempSourceClob, LENGTH(v_source), v_source);
END LOOP;
EXCEPTION
WHEN UTL_HTTP.END_OF_BODY THEN
UTL_HTTP.END_RESPONSE(v_resp);
END;
println('====================');
v_myParser := DBMS_XMLPARSER.NEWPARSER();
DBMS_XMLPARSER.PARSECLOB(v_myParser, v_tempSourceClob);
v_rssDoc := DBMS_XMLPARSER.GETDOCUMENT(v_myParser);
v_tempXMLType := DBMS_XMLDOM.GETXMLTYPE(v_rssDoc);
v_rssEntryList := DBMS_XMLDOM.GETELEMENTSBYTAGNAME(v_rssDoc, 'item');
v_rss_item := v_rss_empty_item;
println
(
v_tempXMLType.EXTRACT('/rss/channel/title/text()').GETSTRINGVAL
|| ' - most recent '
|| DBMS_XMLDOM.GETLENGTH(v_rssEntryList)
|| ' articles:'
);
println('====================');
FOR i IN 1..DBMS_XMLDOM.GETLENGTH(v_rssEntryList) LOOP
v_itemNode := DBMS_XMLDOM.ITEM(v_rssEntryList, i-1);
v_rssItemFields := DBMS_XMLDOM.GETCHILDNODES(v_itemNode);
FOR j IN 1..DBMS_XMLDOM.GETLENGTH(v_rssItemFields) LOOP
v_childnode := DBMS_XMLDOM.ITEM(v_rssItemFields, j-1);
v_childNodeText := DBMS_XMLDOM.GETNODEVALUE(
DBMS_XMLDOM.GETFIRSTCHILD(v_childnode)
);
CASE DBMS_XMLDOM.GETNODENAME(v_childnode)
WHEN 'title' THEN
v_rss_item.title := v_childNodeText;
WHEN 'link' THEN
v_rss_item.link := v_childNodeText;
WHEN 'published' THEN
v_rss_item.pubDate := v_childNodeText;
WHEN 'category' THEN
v_rss_item.category := v_childNodeText;
WHEN 'description' THEN
v_rss_item.description := v_childNodeText;
ELSE
NULL;
END CASE;
END LOOP;
report_rss_item(v_rss_item);
END LOOP;
DBMS_LOB.FREETEMPORARY(v_tempSourceClob);
DBMS_XMLPARSER.FREEPARSER(v_myParser);
println('...End');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(
'Main Procedure:'
|| sqlerrm()
);
RAISE;
END RSS_FEED_READER;
今聞いている曲:
これらの曲がリリースされた時期から随分経っているが、種々の問題は残されたままのような気がする。と考えつつ。。。
ALCATRAZZ -- Hiroshima mon amour
| 固定リンク | 0
コメント