65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 System.XML 构建基于 Web 的 RSS Feed 查看器

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.95/5 (13投票s)

2004年4月21日

2分钟阅读

viewsIcon

138884

downloadIcon

1836

本文档演示了如何构建一个类来解析 RSS Feed,并以易于操作和显示的形式返回详细信息。

Sample Image - screenshot.jpg

引言

在看到互联网上大量可用的下载和查看 RSS Feed 的应用程序后,我一直在想开发一个 .NET 组件来读取、解析和在 aspx 页面中显示 RSS Feed 需要什么。

组件的开发超出了本文的范围,本文将介绍组件用来呈现上述屏幕截图中详细信息的基类。

RSS Feed 旨在通过标准的 XML 解析器进行简单解析。为此,我广泛使用了 System.XML 库,并将其封装在一个单独的类中,以通过 HTTP Stream 加载 XML 文档。

现在开始编写代码!

推导 RSS 版本

始终明智的做法是推导正在解析的文档的版本。所有 RSS Feed 都包含一个版本号。该类目前支持从 v09.1 到 v2.00 的 RSS Feed。由于 XML 解析器提供了一种简单的方法来选择文档中的特定节点,因此随后使用以下函数返回 RSS 版本非常简单。

Public Enum RSSVersion
    version_Unknown = 0
    version_0_91 = 1
    version_0_92 = 2
    version_2_00 = 3
End Enum

Private Function getRSSVersion() As RSSVersion
    Dim myrootNode As XmlNode
    Dim versionAttribute As XmlAttribute
    Dim myRSSVersion As RSSVersion
    myRSSVersion = RSSVersion.version_Unknown
    myrootNode = fetchNode(Document.ChildNodes, "rss")
    versionAttribute = fetchAttribute(myrootNode, "version")
    Select Case versionAttribute.Value
        Case "0.91"
            myRSSVersion = RSSVersion.version_0_91
        Case "0.92"
            myRSSVersion = RSSVersion.version_0_92
        Case "2.00"
            myRSSVersion = RSSVersion.version_2_00
    End Select
    Return myRSSVersion
End Function

RSS 文档遵循标准结构,版本之间只有少数差异。该类仅关注所有版本通用的标准项目。

加载 RSS 标头

RSS 标头包含重要信息,例如作者、标题、源链接和描述。所有这些都加载到下面的结构中,并且可以从该类中访问。

Public Structure RSSHeader
    Dim Title As String
    Dim Link As Uri
    Dim Description As String
    Dim Language As String
    Dim Copyright As String
    Dim managingEditor As String
    Dim webMaster As String
    Dim lastBuildDate As DateTime
End Structure

该结构以类似的方式填充,使用 csxmlparser 类中的解析功能。

Me.myRSSHeader.Copyright = ""
Me.myRSSHeader.Description = ""
Me.myRSSHeader.Language = ""
Me.myRSSHeader.Title = ""
Me.myRSSHeader.webMaster = ""
Me.myRSSHeader.managingEditor = ""
Me.myRSSHeader.lastBuildDate = Nothing
Mybase.DocumentRoot = Me.fetchNode(Document.ChildNodes, "rss")
Mybase.DocumentRoot = Me.fetchNode(Mybase.DocumentRoot.ChildNodes, "channel")
Me.myRSSVersion = Me.getRSSVersion
myNode = fetchNode(Mybase.DocumentRoot.ChildNodes, "title")
If Not IsNothing(myNode) Then Me.myRSSHeader.Title = myNode.InnerText
myNode = fetchNode(Mybase.DocumentRoot.ChildNodes, "link")
If Not IsNothing(myNode) Then Me.myRSSHeader.Link = New Uri(myNode.InnerText)
myNode = fetchNode(Mybase.DocumentRoot.ChildNodes, "description")
If Not IsNothing(myNode) Then Me.myRSSHeader.Description = myNode.InnerText
myNode = fetchNode(Mybase.DocumentRoot.ChildNodes, "language")
If Not IsNothing(myNode) Then Me.myRSSHeader.Language = myNode.InnerText
myNode = fetchNode(Mybase.DocumentRoot.ChildNodes, "copyright")
If Not IsNothing(myNode) Then Me.myRSSHeader.Copyright = myNode.InnerText
myNode = fetchNode(Mybase.DocumentRoot.ChildNodes, "managingEditor")
If Not IsNothing(myNode) Then Me.myRSSHeader.managingEditor = myNode.InnerText
myNode = fetchNode(Mybase.DocumentRoot.ChildNodes, "webMaster")
If Not IsNothing(myNode) Then Me.myRSSHeader.webMaster = myNode.InnerText
myNode = fetchNode(Mybase.DocumentRoot.ChildNodes, "lastBuildDate")
If Not IsNothing(myNode) Then
    Me.myRSSHeader.lastBuildDate = DateTime.Parse(myNode.InnerText)
End If

同样,这只是找到 RSS Feed 文档中的正确节点的一个简单过程。

加载 RSS 项目

我选择将存储在 Feed 中的 RSS 新闻项目存储在从 CollectionBase 继承的自定义集合类中。此集合在下面的结构中存储 RSS 项目的基本信息。

Public Structure RSSItem
    Dim Title As String
    Dim Description As String
    Dim pubDate As DateTime
    Dim Link As Uri
End Structure

这些信息足以在我们的控件中呈现所选项目。并且由于该类已经推导出了 RSS 文档的根节点(Channel 标签),那么只需遍历文档中的所有 Item 节点并按如下方式填充集合即可。

Me.myRSSItems.Clear()

For i = 0 To Mybase.DocumentRoot.ChildNodes.Count - 1
    If Mybase.DocumentRoot.ChildNodes(i).Name = "item" Then
        myItemNode = Mybase.DocumentRoot.ChildNodes(i)
        Dim myItem As RSSItem
        myItem.pubDate = Nothing
        myNode = fetchNode(myItemNode.ChildNodes, "description")
        If Not IsNothing(myNode) Then myItem.Description = myNode.InnerText
        myNode = fetchNode(myItemNode.ChildNodes, "title")
        If Not IsNothing(myNode) Then myItem.Title = myNode.InnerText
        myNode = fetchNode(myItemNode.ChildNodes, "link")
        If Not IsNothing(myNode) Then myItem.Link = New Uri(myNode.InnerText)

        myNode = fetchNode(myItemNode.ChildNodes, "pubDate")
        If Not IsNothing(myNode) Then 
            myItem.pubDate = DateTime.Parse(myNode.InnerText)

        Select Case Me.myRSSVersion
            Case RSSVersion.version_0_91
            Case RSSVersion.version_0_92
            Case RSSVersion.version_2_00
        End Select
        Me.myRSSItems.Add(myItem)
    End If
Next

使用该类

暴露了两个函数,允许从文件或 HTTP Stream 加载 RSS Feed。它们可以按如下方式使用:

Rem Load my RSS Feed from a File
Dim myRSSFeed as New csRSSFeed()
myRSSFeed.Load("C:\feeds\MSDN.rss")

Rem Load my RSS Feed from a HTTP Server
Dim myRSSFeed as New csRSSFeed()
myRSSFeed.LoadFromHTTP("http://www.theregister.co.uk/headlines.rss")

一旦执行了相关的加载函数,就可以在 HeaderVersionitems 属性中找到有关文档的信息,它们分别返回 RSS 标头、文档版本和 RSS 项目。

© . All rights reserved.