Memo

RSSなどのxmlファイルを静的なHTMLに表示させる方法あれこれ


あけましておめでとうございました。本年もよろしくお願いいたします。

さて去年後半、xmlを読み込んでは切ったり貼ったりする仕事が相次いでました。
大変勉強になったので、サンプルや注意点、参考URLなどをまとめておきます。
本当にメモ書きのようなものなので、JS部分のみ抜粋してます。詳しい書き方はサンプルのソース見てくださると助かります。

外部サーバのXMLファイルを読み込む

「ア○ーバブログの更新情報をサイトに載せたい!」なんて時に使えます。

Google AJAX Feed API を使う

シンプルにデータ取得→HTMLに表示はこんな感じでできます。

<script src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
var xmlUrl = "http://arcaxxx.blog21.fc2.com/?xml";	//feedのURL
var setNum = 5;	//表示件数
var setID = "feed";	//表示させる箇所のID
google.load("feeds", "1");
function initialize() {
	var html = '';
    var feed = new google.feeds.Feed(xmlUrl);
    feed.setNumEntries(setNum);
    feed.load(function(result) {
        if (!result.error){
            var container = document.getElementById(setID);
			for (var i = 0; i < result.feed.entries.length; i++) {
				var entry = result.feed.entries[i];
				var title = entry.title;	//記事タイトル取得
				var link = entry.link;		//記事のリンクを取得
				//日付を取得し年月日を整形
				var publishedDate = entry.publishedDate;
				var pubDD = new Date(publishedDate);
				yy = pubDD.getYear();if (yy < 2000) { yy += 1900; }
				mm = pubDD.getMonth() + 1;dd = pubDD.getDate();
				var pubDate = yy +'年'+ mm +'月'+ dd +'日';
				//カテゴリ要素がある場合は取得
				for (var j = 0; j < entry.categories.length; j++) {
					var categorie = entry.categories[j];
				}
				//表示する部分を整形
				html += '<li><a href="' + link + '">' + title +'</a> - ' + categorie + '(' + pubDate + ')</li>';
			}
            container.innerHTML = html;
        }
    });
}
google.setOnLoadCallback(initialize);
</script>

サンプル1

ちょっと凝ったのはこんな感じ

<script type="text/JavaScript" src="js/jquery.js"></script>
<script src="https://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript">
var xmlUrl = "http://mei331.tumblr.com/rss";	//feedのURL
var setNum = 3;	//表示件数
var setID = "feed";	//表示させる箇所のID
google.load("feeds", "1");
function initialize() {
	DD = new Date();HH = DD.getHours();MM = DD.getMinutes();SS = DD.getSeconds();
	xmlUrl = xmlUrl+"?"+HH+MM+SS;	//キャッシュ対策のクエリを付与
    var feed = new google.feeds.Feed(xmlUrl);
    feed.setNumEntries(setNum);
    feed.setResultFormat(google.feeds.Feed.XML_FORMAT);
    feed.load(function(result) {
        if (!result.error){
            var container = document.getElementById(setID);
			var xmlDoc = result.xmlDocument;
            var items = xmlDoc.getElementsByTagName("item");
            var html = '';
			$(xmlDoc).find('item').each(function(){
				title = $(this).find('title').text(); //タイトル取得
				description = $(this).find('description')[0].firstChild.nodeValue; //コンテンツ取得
				link = $(this).find('link').text(); //link取得
				guid = $(this).find('guid').text(); //guid取得

				//日付を取得し年月日を整形
				publishedDate = $(this).find("pubDate").text();
				var pubDD = new Date(publishedDate);
				yy = pubDD.getYear();if (yy < 2000) { yy += 1900; }
				mm = pubDD.getMonth() + 1;dd = pubDD.getDate();
				var pubDate = yy +'年'+ mm +'月'+ dd +'日';

				//表示する部分を整形
				html += '<li><h3><a href="' + link + '">' + title + '</a></h3>';
				html += '<div class="contents">' + description + '</div>';
				html += '<p>'+ guid + '(' + pubDate + ')</p></li>';
			});
            container.innerHTML = html;
        }
    });
}
google.setOnLoadCallback(initialize);
</script>

サンプル2

補足)
Tumblrのコンテンツ(descriptionタグの中身)は、firstChild.nodeValue で取得できます。
ただ、タグ内にある情報を全て表示してしまうので、CSS等での調整が必要だと思います。

自分で書くのが面倒!よくわからない!場合はプラグインで。
これ系のプラグインは色々有りますが、色々試した中では「zRssfeed」がカスタマイズしやすくて便利でした。
プラグインならzRssfeedがオススメ!

参考)jQueryでサイト内に簡単にRSSフィードを組み込めるプラグイン「zRSSFeed」

PHPを使う

google Feed APIを使わないで、外部サーバのXMLファイルを読みに行く為のPHPを設置する方法もあります。
feed2jsというのがあるんですが、これがサクッとできて一番お手軽ですね。
php側で表示数や日付などを設定できます。表示するHTMLには吐き出されたscriptタグを書くだけ。
ただCSSの設定がちょっと面倒なうえ、php側の設定画面が英語なのでちょっと難しいです。
feed2js

参考)小粋空間: RSS Feed(フィード)を表示する

同一サーバのXMLファイルを読み込む

jQueryを使う

jqueryには便利なajax関数があるので、そちらを使って読み込んだりします。

<script type="text/JavaScript" src="js/jquery.js"></script>
<script type="text/javascript">
$(function() {
	var setURL = '../feed';	//feedのURL
	var setNUM = 5;	//表示件数
	var setID = 'feed';	//表示させる箇所のID
	xmlLoad(setURL,setID,setNUM);
});
function xmlLoad(_xmlUrl,_id,_num){
	DD = new Date();HH = DD.getHours();MM = DD.getMinutes();SS = DD.getSeconds();
	var xmlUrl = _xmlUrl+"?"+HH+MM+SS;	//キャッシュ対策のクエリを付与
	var main = this;
	$.ajax({
    url: xmlUrl,
    type: 'GET',
    dataType: 'xml',
    timeout: 10000,
    error: function(){
		_msg = 'error';
		xmlOpen(_msg,_id,_num);
    },
    success: function(_xml){
		main.xml = _xml;
		_msg = 'load';
		xmlOpen(_msg,_id,_num);
	}
	});
	return;
}
var xmlOpen = function(_msg,_id,_num){
	var main = this;
	var html = '';
	var ID = _id;
	var Num = _num;
	if(_msg == 'load'){
		xml = main.xml;
		var channelData = $(xml).find('channel')[0];
		$(channelData).find('item').each(function(i){
			if(i < Num){
			postTitle = $(this).find('title').text();//記事タイトル取得
			postLink = $(this).find('link').text();//記事リンク取得

			//日付を取得し年月日を整形
			publishedDate = $(this).find('pubDate').text();
			var pubDD = new Date(publishedDate);
			yy = pubDD.getYear();if (yy < 2000) { yy += 1900; }
			mm = pubDD.getMonth() + 1;dd = pubDD.getDate();
			var postDate = yy +'年'+ mm +'月'+ dd +'日';

			//カテゴリが1記事に複数あるのである分だけ取得
			var postCategory = '';
			$(this).find('category').each(function(i){
				category = $(this).text();
				if(i <= 0){
					postCategory += category;
				}else{
					postCategory += ',' + category;
				}
			});

			//表示する部分を整形
			html += '<li><a href="' + postLink + '">' + postTitle +'</a> - ' + postCategory + '(' + postDate + ')</li>';
			}
		});
	}else{
		html += '<li>通信エラー</li>';
	}
	$("#"+ID).html(html);
}
</script>

サンプル3

ちょっと複雑なxmlを読み込む場合はこんな感じ

<script type="text/JavaScript" src="js/jquery.js"></script>
<script type="text/javascript">
$(function() {
	var setURL = '../feed';	//feedのURL
	var setNUM = 5;	//表示件数
	var setID = 'feed';	//表示させる箇所のID
	xmlLoad(setURL,setID,setNUM);
});
function xmlLoad(_xmlUrl,_id,_num){
	DD = new Date();HH = DD.getHours();MM = DD.getMinutes();SS = DD.getSeconds();
	var xmlUrl = _xmlUrl+"?"+HH+MM+SS;	//キャッシュ対策のクエリを付与
	var main = this;
	$.ajax({
    url: xmlUrl,
    type: 'GET',
    dataType: 'xml',
    timeout: 10000,
    error: function(){
		_msg = 'error';
		xmlOpen(_msg,_id,_num);
    },
    success: function(_xml){
		main.xml = _xml;
		_msg = 'load';
		xmlOpen(_msg,_id,_num);
	}
	});
	return;
}
var xmlOpen = function(_msg,_id,_num){
	var main = this;
	var html = '';
	var ID = _id;
	var Num = _num;
	var dc ="http://purl.org/dc/elements/1.1/";
	if(_msg == 'load'){
		xml = main.xml;
		var channelData = $(xml).find('channel')[0];
		$(channelData).find('item').each(function(i){
			if(i < Num){
			postTitle = $(this).find('title').text();//記事タイトル取得
			postLink = $(this).find('link').text();//記事リンク取得

			//日付を取得し年月日を整形
			publishedDate = $(this).find('pubDate').text();
			var pubDD = new Date(publishedDate);
			yy = pubDD.getYear();if (yy < 2000) { yy += 1900; }
			mm = pubDD.getMonth() + 1;dd = pubDD.getDate();
			var postDate = yy +'年'+ mm +'月'+ dd +'日';

			postMaster = $(this).find('dc\\:creator').text();	//投稿者名取得
			postDescription = $(this).find('description').text();	//記事冒頭部分取得
			commentNum = $(this).find('slash\\:comments').text();	//コメント数取得

			//カテゴリが1記事に複数あるのである分だけ取得
			var postCategory = '';
			$(this).find('category').each(function(i){
				category = $(this).text();
				if(i <= 0){
					postCategory += category;
				}else{
					postCategory += ',' + category;
				}
			});

			//表示する部分を整形
			html += '<li><a href="' + postLink + '">' + postTitle +'</a> - ' + postMaster + '<br>' + postDescription;
			html += '<span>' + postCategory + '/コメント数:'+ commentNum +' (' + postDate + ')</span></li>';
			}
		});
	}else{
		//エラー時の表示
		html += '<li>通信エラー</li>';
	}
	$("#"+ID).html(html);
}
</script>

サンプル4

補足)
xml内にある<dc:creator>などの要素は、$(xml).find(‘dc\\:creator’) という感じで「:」の前に「\\」を追加することで取得出来ます。
また、今回のサンプルには無いですが、<tags status="date"></tags> というタグがあった場合。
tagsのstatusの値を取得すしたい時は、$(xml).find(‘tags’).attr(‘status’) という指定で取得出来ます。

jQueryを使わない

使わないでやる方法を色々と試してみたんですが、ブラウザによって読み込みの仕様が違うため、難しくて断念しましたorz
jQueryさまさまですね…。
どうしても!となると同一サーバのファイルだけど、Google AJAX Feed APIを使って取得する、という方法になるのでしょうか。

その他xmlをjsで扱う場合に注意することなど

  • ローカルでxmlを参照する場合、表示するhtmlより下位の階層にあること
    セキュリティ的な問題で、ローカルで参照する場合は下階層に無ければ参照できません。
  • Google Chromeはローカルでxmlを参照することができない
    できるようにする方法ももちろんありますが、セキュリティの問題もありますので、自己責任でお願いします。
    参考)Google Chrome でAjaxを利用しローカルファイルにアクセスする[to-R]
  • xmlのキャッシュに注意
    「xmlを更新しても更新されない!」場合はキャッシュを読んでしまってる可能性があります。
    xmlファイルの末尾にタイムスタンプのクエリなどを追加しておくと回避できます。
    (サンプル1以外にはキャッシュ対策のクエリを追加してますので参考までに)
  • xmlファイルのエラーに注意
    「jsでおかしい部分はないのに、うまく読み込めない!」場合はxmlファイル自体がパースエラーを起こしている場合もあります。また、xmlファイルは「&」をそのまま書いているとエラーになります。「&amp;」にしておきましょう。
    パースエラーかどうかはxmlファイルをfirefoxなどのブラウザで読み込むことで確認できます。
  • xmlに記載したタグを表示したい
    xmlの表示したい部分を<![CDATA[~]]>で囲むと幸せになれます。
  • 文字化けする時はJSや読み込むXML、表示するHTMLの文字コードをチェック
    結構それが原因だったりします。特にIEさんとかIEさんとか…
  • Google Feed API Key は必要?
    色んなサイトで呪文のように「まずはGoogle Feed API Keyを取得します」とあるんですが、どうやら不要のようです?(ちょっと曖昧)サンプルではソースを見ていただければ分かる通り使ってはいませんが、動いてはいます。
    JSONの取得のみならAPI Keyは要らない、という記述はみつけましたが。
    参考)Google AJAX Feed APIのJSONをjQueryで取得する [Feed to JSON] : ずっと工事中
    ある日突然必要になる可能性もなきにしもあらず。公式のリンクがあちこちNot Foundで上手く探せないですね。
    こちらは引き続き探しておきたいと思います。

こんなもんでしょうか。
去年このブログを開設したけど、そんなに書かなくなってしまい。原因を考えて、webだけにくくってるからかなーと
思い至ったので、それ以外のことも書いていきたいなーと思います。はい。
とかいいつつ、webの記事で始まりましたが、気にしないでください。

今年はもうちょっとブログ更新できるようにするぞー@・ェ・@

参考記事一覧)
・Google AJAX Feed API入門:http://www.ajaxtower.jp/googleajaxfeed/
・Google Feed APIで用意されている要素以外の要素にアクセスする方法 – KUMA TYPE:http://blog.kumacchi.com/2011/01/google_feed_api.html
・Google AJAX Feed APIのJSONをjQueryで取得する [Feed to JSON] : ずっと工事中:http://blog.livedoor.jp/eeu/archives/55284669.html
・小粋空間: RSS Feed(フィード)を表示する:http://www.koikikukan.com/archives/2006/12/11-003811.php
・jQueryでサイト内に簡単にRSSフィードを組み込めるプラグイン「zRSSFeed」:http://black-flag.net/jquery/20110228-2697.html
・Using jQuery on WSH – 葉っぱ日記:http://d.hatena.ne.jp/hasegawayosuke/20090928/p1
・Google Chrome でAjaxを利用しローカルファイルにアクセスする[to-R]:http://blog.webcreativepark.net/2010/06/24-202820.html

MemoTags , , 2012年01月25日 01:47

コメントを残す




使用可能タグ: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>