HTTP通信、RSS解析を行うVBAを記述する

外部ユーザ関数getFeedを定義します。

[リスト1]HTTP通信、RSS解析を行う

Private Function getFeed(url As String, genre As String) As String

    '(1)URLの入力チェック
    '(略)

    '(2)HTTP通信によるリクエスト送信
    '(略)

    '(3)XMLデータの解析
    Dim xmldata As MSXML2.DOMDocument
    Dim root As MSXML2.IXMLDOMElement
    Dim itemList As MSXML2.IXMLDOMNodeList
    Dim item As MSXML2.IXMLDOMNode

    Set xmldata = New MSXML2.DOMDocument
    xmldata.LoadXML resText 'レスポンスをXML文書として格納

    '(4)XML文書のルート要素にアクセス
    Dim feedFormat As String: feedFormat = ""
    Set root = xmldata.DocumentElement
    Select Case root.tagName
    Case "rdf:RDF"
        feedFormat = "rss1"
    Case "rss"
        If root.getAttribute("version") = "2.0" Then
            feedFormat = "rss2"
        End If
    End Select
    If feedFormat = "" Then
        getFeed = "不正な形式"
        Exit Function
    End If

    '(5)記事を「item」要素のリストとして取得
    Set itemList = root.getElementsByTagName("item")

    '(6)itemListの件数だけ、記事リスト配列を広げる(既存データは保持)
    ReDim Preserve artList(nofList + itemList.Length - 1)
    Dim value As String
    For i = 0 To itemList.Length - 1
        Set item = itemList(i)
        For j = 0 To item.ChildNodes.Length - 1
            value = item.ChildNodes(j).Text
            Select Case item.ChildNodes(j).nodeName
            Case "title"
                artList(nofList + i).title = value
            Case "link"
                artList(nofList + i).link = value
            Case "description"
                artList(nofList + i).description = cdataConv(value)
            Case "dc:date"
                If feedFormat = "rss1" And value <> "" Then
                    artList(nofList + i).pubDate = convISO8601(value)
                End If
            Case "pubDate"
                If feedFormat = "rss2" And value <> "" Then
                    artList(nofList + i).pubDate = convRFC822(value)
                End If
            End Select
        Next j
        artList(nofList + i).genre = genre
    Next i
    nofList = nofList + itemList.Length
    Set xmldata = Nothing 'XMLオブジェクトを解放
    getFeed = "OK"

End Function

(1)受け取った引数urlが空文字の場合は、「URL未入力」を返して終了します。
(2)URLに対してリクエストを送信し、成功したら、レスポンスをstatusに格納します。 (3)オブジェクト変数xmldataにデータを読み込みます。
(4)フィード形式変数feedFormatを初期化(空文字)しておきます。 ルート要素のタグ名が"rdf:RDF"の場合は、"rss1"を設定します。
"rss"の場合は、バージョン属性も取得し、"2.0"だった場合は、"rss2"を設定します。
feedFormatが空文字の場合は、不正な形式と判断し、getFeed関数を終了します。
(5)記事を取り出す処理です。1件分の記事は、RSS1.0、2.0ともにitem要素なので、getElementsByTagNameメソッドにより取り出し、itemListオブジェクトに格納します。

図5.XMLデータの構造

(6)これを一旦、構造型配列artListに格納するため、ReDim Preserve命令により件数をitemListに合わせて拡張(既存データは保持)します。

itemListからインデックスを使って、item要素ごとにその子要素の配列を取得します。この中に<title>などがあるはずですが、要素の有無、順序はサイトによって異なります。このため子要素すべてを走査し、名称が一致すれば、要素ごとに必要な処理を行った上で、artListに格納します。

description要素には、HTMLタグが含まれる可能性があるため、ユーザ定義関数cdataConvにより、<~>の形の文字列を正規表現(後述)を使って、空文字に置換します。 日時形式はRSS1.0ではISO8601形式(例.2012-01-14T07:33:22+09:00)、RSS2.0ではRFC822形式(例.Sat, 14 Jan 2012 07:33:22 +0900)ですので、それぞれユーザ定義関数にて変換したのちartList配列に格納します。

nofListは、フィードの記事数itemList.lengthだけ加算し、xmldataオブジェクトを解放し、「OK」を返して終了します。