RSSリーダ(RSS0.91対応)

戻る

import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
import java.util.*;

/**
* $Id: rss0_91.html,v 1.1 2009/06/22 16:12:24 kishi Exp kishi $
* @author KISHI Yasuhiro
*/

public class RSS0_91 {

    /** ドキュメントのルート要素 */
    private Element root;

    private RSSEntity channel = null;
    private List<RSSEntity> itemList = null;

    public static void main( String[] args ) {

        if ( args.length != 1 ) {
            System.out.println( "usage: java -cp . RSS0_91 [URI|fileName]" );
            System.exit( -1 );
        }
        String source = args[ 0 ];

        try {

            /////////////////////////////////////////////////////
            // RSSリーダのインスタンス生成
            /////////////////////////////////////////////////////
            RSS0_91 reader = new RSS0_91( source );

            /////////////////////////////////////////////////////
            // ルート要素から再帰的に走査していく
            /////////////////////////////////////////////////////
            reader.traverse();

            // ダンプする
            reader.iterateAll();

        } catch ( Exception e ) {
            e.printStackTrace();
        }

    }

    public RSS0_91( String source ) throws Exception {
        init( source );
    }

    private void init( String source ) throws Exception {
        //------------------------------------------------------------------------------------
        // ドキュメントビルダーファクトリを生成
        //------------------------------------------------------------------------------------
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        //------------------------------------------------------------------------------------
        // 【重要】 -- CDATAノードの取り出し方です --
        // このファクトリで作成されたパーサが CDATA ノードを Text ノードに変換し、
        // それを隣接 (存在する場合) Text ノードに追加するように指定します。
        // デフォルトでは、この値は false に設定されます。
        //------------------------------------------------------------------------------------
        factory.setCoalescing( true );

        //------------------------------------------------------------------------------------
        // ドキュメントビルダーを生成
        //------------------------------------------------------------------------------------
        DocumentBuilder builder = factory.newDocumentBuilder();

        //----------------------------------------------------------------
        // パースを実行してDocumentオブジェクトを取得
        //----------------------------------------------------------------
        Document doc = builder.parse( source );

        System.out.println( "【XMLのバージョン】" + doc.getXmlVersion() );
        System.out.println( "【文書のエンコーディング】" + doc.getXmlEncoding() );

        root = doc.getDocumentElement();

        System.out.println( "【ルート要素のタグ名】" + root.getTagName() );
        System.out.println( "【ルート要素の属性】" + root.getAttribute( "version" ) );

        // --- ここまではXML文書を読むための共通処理

    }

    /**
    * セットされた情報を全て列挙する
    */
    public void iterateAll() {

        if ( channel != null ) {
            System.out.println();
            System.out.println( "/** channel */" );
            channel.iterate();
        }

        if ( itemList != null ) {
            Iterator iterator = itemList.iterator();
            while ( iterator.hasNext() ) {
                RSSEntity item = ( RSSEntity ) iterator.next();
                System.out.println();
                System.out.println( "/** item */" );

                item.iterate();
            }
        }
    }


    public void traverse() {
        // 子要素のリストを取得 -- getFirstChild()はNodeクラスが持つメソッドなのでキャストする
        Node childNode = ( ( Node ) root ).getFirstChild();

        while ( childNode != null ) {
            String nodeName = childNode.getNodeName();

            if ( "channel".equals( nodeName ) ) {
                // System.out.println( nodeName );
                parseChannel( childNode );
            }

            childNode = childNode.getNextSibling();
        }

    }

    private void parseChannel( Node node ) {

        channel = new RSSEntity();

        // 子要素のリストを取得 -- getFirstChild()はNodeクラスが持つメソッドなのでキャストする
        Node childNode = node.getFirstChild();

        while ( childNode != null ) {
            String nodeName = childNode.getNodeName();

            if ( "title".equals( nodeName )
                    || "link".equals( nodeName )
                    || "description".equals( nodeName )
                    || "language".equals( nodeName )
                    || "lastBuildingDate".equals( nodeName )
                    || "docs".equals( nodeName )
               ) {
                channel.put( nodeName, childNode.getFirstChild().getNodeValue() );

            } else if ( "item".equals( nodeName ) ) {
                parseItem( childNode );
            }

            childNode = childNode.getNextSibling();
        }
    }

    private void parseItem( Node node ) {

        if ( itemList == null ) {
            itemList = new LinkedList();
        }

        RSSEntity item = new RSSEntity();

        // 子要素のリストを取得
        Node childNode = node.getFirstChild();

        while ( childNode != null ) {
            String nodeName = childNode.getNodeName();

            if ( "title".equals( nodeName )
                    || "link".equals( nodeName )
                    || "description".equals( nodeName )
               ) {

                String nodeValue = "";
                if ( !childNode.hasChildNodes() ) {
                    /**
                    * 要素に値がない場合はnull例外が発生するので止むを得ず対応
                    */ 
                    // System.err.println( "*** NULL *** " );
                    // DO NOTHING
                } else {
                    nodeValue = childNode.getFirstChild().getNodeValue();
                }
                // System.out.println( nodeName + ": " + nodeValue );
                item.put( nodeName, nodeValue );
            }

            childNode = childNode.getNextSibling();
        }

        itemList.add( item );


    }

    /**
        * チャネル、イメージ、アイテムなどを格納するクラス
        */
    private class RSSEntity {
        private Map<String, String> map;

        public RSSEntity() {
            map = new LinkedHashMap();
        }

        public void put( String key, String value ) {
            map.put( key, value );
        }

        public String get
            ( String key ) {
            return map.get( key );
        }

        public void iterate() {
            Iterator iterator = map.keySet().iterator();
            while ( iterator.hasNext() ) {
                String key = ( String ) iterator.next();
                String value = map.get( key );
                System.out.println( key + "\t" + value );
            }
        }
    }

}

■実行結果

$ java -cp . RSS0_91 "http://www.doblog.com/weblog/RSSServlet?CMD=LATEST&userid=7160&TYPE=RSS_0_91"
【XMLのバージョン】1.0
【文書のエンコーディング】UTF-8
【ルート要素のタグ名】rss
【ルート要素の属性】0.91

/** channel */
title	アラベスク組曲
link	http://www.doblog.com/weblog/myblog/7160
description	All in love is FAIR. /** * 殆どそこはかとない * 絵日記ならぬ * 「写真日記」です。 */
language	ja
docs	http://backend.userland.com/stories/rss091

/** item */
title	多摩モノレール@立川
link	http://www.doblog.com/weblog/myblog/7160/2524962#2524962
description	

/** item */
title	日本−ドイツ戦は31日午前3時半開始 (日刊スポーツ)
link	http://www.doblog.com/weblog/myblog/7160/2524855#2524855
description	<i>日本協会は1日、日本代表のW杯前最後の強化試合となるドイツでの国際親善試合2試合の開始時間を明らかにし、ドイツ戦(レーバークーゼン)は30日午後8時半(日本時間31日午前3時半)、マルタ戦(デュッセルドルフ)は6月4日午後3時(同10時)となった。</i> だそうです。

/** item */
title	マスター・アンド・コマンダー
link	http://www.doblog.com/weblog/myblog/7160/2524190#2524190
description	これもDVD借りてきて観ました。 海原での大嵐の部分が迫力ありました。 内容的には、これもリーダーシップがテーマなんだな、きっと。 「任務優先」を至上のものとしている船長には、親友であり部下である医者との間との葛藤があり、そのあたりがストーリーの展開に深みを与えている。 こういう役をやらせると、ラッセル・クロウはキメてくれます。 #ガラパゴス島、行ってみたいです。

/** item */
title	水辺の風景@立川公園
link	http://www.doblog.com/weblog/myblog/7160/2522708#2522708
description	

/** item */
title	カルガモ@立川公園
link	http://www.doblog.com/weblog/myblog/7160/2522674#2522674
description	

/** item */
title	カルガモ@立川公園
link	http://www.doblog.com/weblog/myblog/7160/2522619#2522619
description	ここの鴨は人懐こい。 というか、人からほぼ飼育されているのに等しい。 近所に住む人(犬の散歩をしていたりする)が餌を供給しているようだ。 私にぜんぜん警戒しないで、こんな距離まで例のユーモラスな歩き方でと近づいてきます。

/** item */
title	花@立川公園
link	http://www.doblog.com/weblog/myblog/7160/2522560#2522560
description	黄色い菖蒲である。 そういえば端午の節句だ。菖蒲湯に浸かろう!

/** item */
title	鴨の昼寝@立川公園
link	http://www.doblog.com/weblog/myblog/7160/2522518#2522518
description	鴨はこうやって御昼寝するわけです。

/** item */
title	タンポポ
link	http://www.doblog.com/weblog/myblog/7160/2522488#2522488
description	風に吹かれて、この種子はどこに飛んでいくのか・・・ 想像してみた。

/** item */
title	貝殻坂@立川公園
link	http://www.doblog.com/weblog/myblog/7160/2522439#2522439
description	暑かった。なんと関東以西では真夏日のところが多かったらしい。 ということで、今日は再び立川公園まで遠征。 今回は珍しく立川公園までの多摩川サイクリングロードではわき目もふらず、一心にひたすら走り抜けた。日差しが強かったんで、かなり日焼けしたかも・・・ 立川公園内に入りようやく一息。 今日はかなり体力を消耗している。このぐらいがいいかもしれない。 #おかげでだいぶ腹もへこんできた(笑)

/** item */
title	コエンザイム
link	http://www.doblog.com/weblog/myblog/7160/2521775#2521775
description	たまにはこんなものも摂取しています。

/** item */
title	STATISTICS
link	http://www.doblog.com/weblog/myblog/7160/2521090#2521090
description	ポイント: 0.0 総ブログ数: 0 総アクセス数: 0 タイトル: Doblog - メッセージ URL: http://www.doblog.com/weblog/myblog/7000 ポイント: 314.2 総ブログ数: 20 総アクセス数: 6283 タイトル: Doblog - 国際化時代のキャリア戦略 - URL: http://www.doblog.com/weblog/myblog/7001 ポイント: 0.0 総ブログ数: 0 総アクセス数: 24 タイトル: Doblog - デジカメ写真集 - URL: http://www.doblog.com/weblog/myblog/7002 ポイント: 0.0 総ブログ数: 0 総アクセス数: 85 タイトル: Doblog - デジカメ写真集(石田) - URL: http://www.doblog.com/weblog/myblog/7003 ポイント: 6.6 総ブログ数: 66 総アクセス数: 434 タイトル: Doblog - Light Metals Smoothie - URL: http://w...

/** item */
title	ベニスの商人
link	http://www.doblog.com/weblog/myblog/7160/2520356#2520356
description	DVD借りて、観ました。いつも「時間差レンタル」ですが・・・でも新作なので2泊3日。 急いで見ることに。 なんだかんだいって、正直、一番の感想は、ユダヤ商人シャイロックが非常に可哀想で同情したくなったこと。 勿論アル・パチーノの演技が素晴らしかった。 このストーリー(勿論シェークスピア原本)は普遍的な人間の葛藤が描かれている。だから時代を超えて問題提起を今を生きる人にも訴えてくるのでしょう。 結局、この物語は、法とは「詭弁」である、ということがひとつのテーマになっているのかと思う。

/** item */
title	慈恵医大病院の風景
link	http://www.doblog.com/weblog/myblog/7160/2519165#2519165
description	

/** item */
title	stitch
link	http://www.doblog.com/weblog/myblog/7160/2519152#2519152
description	【名-1】 ひと針、縫い目、一針{いっしん}(の縫合{ほうごう})、編目{あみめ}、ステッチ、綴じ、布地{ぬのじ} 【名-2】 さしこみ、脇腹{わきばら}の痛み 【名-3】 〈話〉わずか、ほんの少し 【自動】 縫う 【他動】 〜を縫う、縫い合わせる、とじる ・ He stitched the torn part of the skirt. 彼はスカートの破れた部分を縫い合わせた。 【レベル】5、【発音】sti't∫、【@】スティッチ、ステッチ、【変化】《動》stitches | stitching | stitched stitch a button onto a shirt シャツにボタンを付ける stitch a piece of brightly-coloured embroidery 明るい色の刺しゅうをする stitch a rip ほころびを縫う stitch a wound 傷口{きずぐち}を縫う stitch abscess 縫合部膿瘍{ほうごうぶ のうよう}


戻る

inserted by FC2 system