RSS解析

DOM(その1)、XSLT(その2)を使ったRSS解析を紹介。

 



 

【その1】:DOMを使ってRSSを解析

XMLフォーマットで作られたRSS(Rich Site Summary)をWebブラウザのXMLパーサーを使って解析してみます。

XML解析は、サーバーサイドでの解析ではなく、クライアント側のWebブラウザ上で行います。
手軽に試せる半面、セキュリティの関係でローカルマシン上でしか実行できません。

# インターネット上にアップロードしてもセキュリティ・レベルを下げないと実行できません。
# なので、ローカルで実行する勉強用と考えてください。

ブラウザはMicrosoft Internet Exproler 5.5以降を使用します(MSXMLを利用)。

javaScriptソースコード (rss.js)
var cnt=0;
var treeName = new Array();   // ツリー名(RSSタイトル)記憶用配列
var treeExpand = new Array(); // ツリー展開フラグ用配列

// RSSのタイトルと表示領域作成
function addRss(rssTitle,rssUri)
{
  treeName[cnt]=rssTitle; // RSSタイトルを記憶しておく
  treeExpand[cnt]=false;   // ツリー展開フラグON
  // HTMLソース作成
  document.write("<div id='" + rssTitle + "'>");
  document.write(nodeSrc(rssTitle,rssUri,true));
  document.write("</div>");
  cnt++; // 配列数をカウントアップ
}

// ツリーノード部分のHTMLソースを返す
function nodeSrc(rssTitle,rssUri,flg)
{
  // リンクをクリックした時listRssが呼び出すようHTMLソースを作成
  var sHtm = "<a href='javascript:listRss(\"" + rssTitle + "\",\"" + rssUri + "\")'>";
  sHtm += rssTitle + "</a>";
  return sHtm;
}

// RSSを読み込み表示
function listRss(rssTitle,rssUri)
{
  var sHtm;  // HTMLソース記憶用の変数
  var i,j;
  // 配列の中からRSSタイトルが一致するindex値を求める
  for(i=0;i<cnt;i++)
    if(treeName[i]==rssTitle) break;

  // ツリー展開済みかチェックし、展開済みならクローズ処理
  if(treeExpand[i]){
    sHtm = nodeSrc(rssTitle,rssUri,true);
    document.all.item(rssTitle).innerHTML = sHtm;
    treeExpand[i]=false;
    return;
  }

  // ツリー展開処理
  treeExpand[i]=true;

  // DOMの準備
  var xmldoc = new ActiveXObject("Microsoft.XMLDom");
  xmldoc.async = false;
  xmldoc.load(rssUri); // RSSを読み込む
  var rootNode;
  // RSS 1.0用のルートノードが存在するかチェック
  if(xmldoc.getElementsByTagName("rdf:RDF").length>0)
    rootNode = xmldoc.getElementsByTagName("rdf:RDF").item(0);  // RSS1.0
  else
    rootNode = xmldoc.getElementsByTagName("rss").item(0);      // RSS2.0
  // 各RSS用のタグやテキストを解析
  var channelNode = rootNode.getElementsByTagName("channel").item(0);
  var link  = channelNode.getElementsByTagName("link").item(0).text;
  var itemNodes = rootNode.getElementsByTagName("item");
  var itemTitle,itemLink,itemDate,strDate,strTime,strDateBk="",itemSub,itemSubBk="";
  // nodeSrcを実行しHTMLソースを準備(RSSタイトル部分)
  sHtm = nodeSrc(rssTitle,rssUri,false) + "<br>";
  // <item>タグの数だけループ
  for(i=0;i<itemNodes.length;i++){
    // <title>,<link>のテキストを取得
    itemTitle = itemNodes.item(i).getElementsByTagName("title").item(0).text;
    itemLink  = itemNodes.item(i).getElementsByTagName("link").item(0).text;
    // 日時用の<dc:date>タグの有無をチェックし、有れば文字列変換
    if(itemNodes.item(i).getElementsByTagName("dc:date").length>0){
      itemDate  = itemNodes.item(i).getElementsByTagName("dc:date").item(0).text;
      strDate = itemDate.substr(0,4) + "/" + itemDate.substr(5,2) + "/" + itemDate.substr(8,2);
      strTime = itemDate.substr(11,2) + ":" + itemDate.substr(14,2);
      // 1個前のものと日付が切り替わったかチェック
      if(strDate!=strDateBk){
        sHtm += "<font size=-2>&emsp;" + strDate + "</font><br>";
        strDateBk = strDate;
      }
      // <item>タグの子ノードに<dc:subject>が有るかチェック
      for(j=0;j<itemNodes.item(i).childNodes.length;j++){
        if(itemNodes.item(i).childNodes(j).nodeName=="dc:subject"){
          // タイトルを取得
          itemSub = itemNodes.item(i).childNodes(j).text;
          if(itemSub!=itemSubBk){
            sHtm += "<font size=-2>&emsp;&emsp;&emsp;[" + itemSub + "]</font><br>";
            itemSubBk = itemSub;
          }
        }
      }
      sHtm += "&emsp;&emsp;&emsp;&emsp;";
      if((strTime.length<=1) || (strTime=="00:00"))
        sHtm += "&ensp;&ensp;"; // 日時が無効な形式の場合、空白
      else
        sHtm += "<font size=-2>" + strTime + "</font>";
      // リンク付きタイトルを作成
      sHtm += "&emsp;<a href='" + itemLink + "'>" + itemTitle + "</a><br>";
    }else if(itemNodes.item(i).getElementsByTagName("pubDate").length>0){
      itemDate  = itemNodes.item(i).getElementsByTagName("pubDate").item(0).text;
      sHtm += "&emsp;<a href='" + itemLink + "'>" + itemTitle + "</a>";
      sHtm += "&emsp;&emsp;<font size=-2>" + itemDate + "</font><br>";
    }else{
      sHtm += "&emsp;<a href='" + itemLink + "'>" + itemTitle + "</a><br>";
    }
  }
  sHtm += "<br>";
  document.all.item(rssTitle).innerHTML = sHtm;
}
HTMLソースコード
<html>
<head>
<script language="JavaScript" src="rss.js"></script>
</head>
<body>
<script language="Javascript">
  addRss('asahi.com','http://www3.asahi.com/rss/index.rdf'); // 試しにasahi.comのRSSを追加 
</script>
</body>
</html>

RSS速報 RSS速報 では、↑このJavaScriptをベースにRSS解析しています。

 

 

【その2】XSLTを使ってRSSを解析

XMLフォーマットで作られたRSS(Rich Site Summary)をWebブラウザのXMLパーサーを使って解析してみます。

XML解析は、サーバーサイドでの解析ではなく、クライアント側のWebブラウザ上で行います。
手軽に試せる半面、セキュリティの関係でローカルマシン上でしか実行できません。

# インターネット上にアップロードしてもセキュリティ・レベルを下げないと実行できません。
# なので、ローカルで実行する勉強用と考えてください。

ブラウザはMicrosoft Internet Exproler 5.5以降を使用します(MSXMLを利用)。
<2007/02/19> Firefox、Operaにも対応しました。

XSLTソースコード (rss.xsl)
RSS 1.0形式のXMLタグを解析しHTMLに変換するXSLTサンプルソース。
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
                xmlns:dc="http://purl.org/dc/elements/1.1/"
                xmlns:purl="http://purl.org/rss/1.0/"
                version="1.0">
<xsl:template match="/">
  <html><head><title>RSS/RDF</title></head><body>
    <table border="1" cellpadding="0" cellspacing="0" bordercolor="#ddddee">
      <tr>
        <th colspan="3" bgcolor="#ddddee">
          <xsl:value-of select="/rdf:RDF/purl:channel/purl:title" />
        </th>
      </tr>
      <xsl:apply-templates select="/rdf:RDF/purl:item" />
    </table>
  </body></html>
</xsl:template>

<xsl:template match="purl:item">
  <xsl:variable name="itemUrl" select="purl:link" />
  <tr>
    <td>
      <xsl:value-of select="concat(substring(dc:date,0,11),' ',substring(dc:date,12,5))"/>
    </td>
    <td><xsl:value-of select="dc:subject"/></td>
    <td>
      <xsl:element name="a">
        <xsl:attribute name="href"><xsl:value-of select="$itemUrl" /></xsl:attribute>
        <xsl:attribute name="target">_blank</xsl:attribute>
        <xsl:value-of select="purl:title"/>
      </xsl:element>
    </td>
  </tr>
</xsl:template>

</xsl:stylesheet>
HTMLソースコード
こちらはHTML。
<html>
<head>
<script language="JavaScript"><!--
function viewList(xmlFile,xslFile) {
    if (window.ActiveXObject) {
        // IE
        var xmlDoc  = new ActiveXObject("Microsoft.XMLDOM");
        var xsltDoc = new ActiveXObject("Microsoft.XMLDOM");

        xmlDoc.async = false;
        xsltDoc.async = false;
        xmlDoc.load(xmlFile);
        xsltDoc.load(xslFile);

        document.getElementById("viewArea").innerHTML = xmlDoc.transformNode(xsltDoc);
    }else if (document.implementation && document.implementation.createDocument) {
        // FireFox
        var xmlDoc  = document.implementation.createDocument("", "", null);
        var xsltDoc = document.implementation.createDocument("", "", null);

        xmlDoc.async = false;
        xsltDoc.async = false;
        xmlDoc.load(xmlFile);
        xsltDoc.load(xslFile);

        var xsltPro = new XSLTProcessor();
        xsltPro.importStylesheet(xsltDoc);
        document.getElementById("viewArea").innerHTML = "";
        document.getElementById("viewArea").appendChild(xsltPro.transformToFragment(xmlDoc, document));
    }else{
        alert("このブラウザでは実行できません")
    }
}
--></script>
</head>
<body onload="viewList('index.xml','rss.xsl')">

<div id="viewArea" align="center"></div>
</body>
</html>