RSS Nachrichten, sogenannte Feeds, werden immer beliebter und bieten eine ideale Möglichkeit, den Besucher einer Webseite über die neuesten Informationen auf den Laufenden zu halten. Wer selber eine Webseite betreibt, der stellt auch meist ein oder mehrere Feeds zur Verfügung. Wie wäre es nun, wenn man diese „Nachrichten von zu Hause“ direkt in der Anwendung anzeigt, so dass der Anwender Ihrer Software immer auf den neuesten Stand der Dinge bleibt. Wir kennen das z.B. vom der Visual Studio Startseite, wo uns Microsoft über die neuesten Visual Studio Schlagzeilen informiert. Das nachfolgende VB2008 Klassenmodul „RSSLinqReader“ hilft uns dabei, dies zu realisieren. Die Reader Klasse liest dabei asynchron einen RSS XML-Stream von einer angegebenen URL. Der Stream wird mit LINQ ausgewertet und in einen formatierten HTML-Stream umgewandelt, so dass dieser direkt in einem WebBrowser Steuerelement angezeigt werden kann. Option Infer On Imports System.Net Imports System.Text Imports System.ComponentModel ''' <summary> ''' EventArgs Klasse, die den HTMLStream an die aufrufende Form übergibt. ''' </summary> Public Class RSSReceivedEventArgs Inherits EventArgs Private m_HTMLStream As String Public Sub New(ByVal value As String) m_HTMLStream = value End Sub Public ReadOnly Property HTMLStream() As String Get Return m_HTMLStream End Get End Property End Class ''' <summary> ''' RSSReader Klasse zum Abrufen von RSS 2.0 Feeds. ''' </summary> ''' <remarks> ''' Die RSSReader Klasse liest asynchron einen RSS XML-Stream von ''' einer angegebenen URL. Der Stream wird mit LINQ ausgewertet ''' und in ein HTML-Stream umgewandelt, so dass dieser direkt in ''' einem WebBrowser angezeigt werden kann. ''' ''' Juni 2009 - VB-Power.net ''' http://www.vb-power.net ''' </remarks> Public Class RSSLinqReader ' Member Variablen Private m_URL As String Private m_SkipDays As Integer = 30 Private m_RefreshInterval As Integer = 60 Private m_BackColor As Color = Color.White Private m_ForeColor As Color = Color.Black Private m_FontName As String = "Tahoma" Private m_FontSize As String = "x-small" Private dWeb As New WebClient Private RefreshTimer As New Timer Public Event RSSReceived(ByVal sender As Object, ByVal e As RSSReceivedEventArgs) ''' <summary> ''' Initialisiert die Klasse mit der angegebenen URL ''' </summary> ''' <param name="URL">Die URL des RSS-Feeds</param> Public Sub New(ByVal URL As String) m_URL = URL RefreshTimer.Enabled = False AddHandler RefreshTimer.Tick, AddressOf RefreshTimerTick AddHandler dWeb.DownloadStringCompleted, AddressOf DownloadStringCompleted End Sub ''' <summary> ''' Legt die Hintergrundfarbe im HTML fest, oder liest diese aus. ''' </summary> ''' <value>Color</value> <Description("Legt die Hintergrundfarbe im HTML fest, oder liest diese aus."), _ Category("HTML Settings"), DefaultValue(GetType(Color), "White")> _ Public Property BackColor() As Color Get Return m_BackColor End Get Set(ByVal value As Color) m_BackColor = value End Set End Property ''' <summary> ''' Legt die Vordergrundfarbe im HTML fest, oder liest diese aus. ''' </summary> ''' <value>Color</value> <Description("Legt die Vordergrundfarbe im HTML fest, oder liest diese aus."), _ Category("HTML Settings"), DefaultValue(GetType(Color), "Black")> _ Public Property ForeColor() As Color Get Return m_ForeColor End Get Set(ByVal value As Color) m_ForeColor = value End Set End Property ''' <summary> ''' Legt den FontNamen im HTML fest, oder liest diesen aus. ''' </summary> ''' <value>String: FontName</value> <Description("Legt den FontNamen im HTML fest, oder liest diesen aus."), _ Category("HTML Settings"), DefaultValue(GetType(String), "Tahoma")> _ Public Property FontName() As String Get Return m_FontName End Get Set(ByVal value As String) m_FontName = value End Set End Property ''' <summary> ''' Legt die Size für den HTML-Font fest, oder liest diese aus. ''' </summary> ''' <value>String: Size</value> <Description("Legt die Size für den HTML-Font fest, oder liest diese aus."), _ Category("HTML Settings"), DefaultValue(GetType(String), "x-small")> _ Public Property FontSize() As String Get Return m_FontSize End Get Set(ByVal value As String) m_FontSize = value End Set End Property ''' <summary> ''' Legt den Intervall in Minuten für das automatische erneute Einlesen ''' des Feeds fest, oder liest diesen aus. ''' </summary> ''' <value>Integer: Intervall in Minuten</value> <Description("Legt den Intervall in Minuten für das automatische erneute Einlesen " & _ "des Feeds fest, oder liest diesen aus."), _ Category("Feed Settings"), DefaultValue(GetType(Integer), "60")> _ Public Property RefreshInterval() As Integer Get Return m_RefreshInterval End Get Set(ByVal value As Integer) m_RefreshInterval = value End Set End Property ''' <summary> ''' Legt die Gültigkeit eines Items im Feed fest, oder liest diese aus. ''' </summary> ''' <value>Integer: Gültigkeit in Tage</value> <Description("Legt die Gültigkeit eines Items im Feed fest, oder liest diese aus."), _ Category("Feed Settings"), DefaultValue(GetType(Integer), "30")> _ Public Property SkipDays() As Integer Get Return m_SkipDays End Get Set(ByVal value As Integer) m_SkipDays = value End Set End Property ''' <summary> ''' Startet den Download des Feeds. ''' </summary> Public Sub ReceiveRSS() Try dWeb.Encoding = Encoding.Default dWeb.CachePolicy = New Cache.RequestCachePolicy( _ Cache.RequestCacheLevel.NoCacheNoStore) dWeb.DownloadStringAsync(New Uri(m_URL)) RefreshTimer.Interval = m_RefreshInterval * 60000 RefreshTimer.Enabled = True Catch ex As Exception Throw ex End Try End Sub Private Sub RefreshTimerTick(ByVal sender As Object, ByVal e As System.EventArgs) RefreshTimer.Enabled = False Me.ReceiveRSS() End Sub Private Sub DownloadStringCompleted(ByVal sender As Object, _ ByVal e As System.Net.DownloadStringCompletedEventArgs) Static OldStream As String = String.Empty If e.Error Is Nothing Then ' RSS-DownloadString an XElement übergeben Dim rss As XElement = XElement.Load(New System.IO.StringReader(e.Result)) ' LINQ Abfrage auf die allgemeinen Channel-Informationen Dim Info = From channel In rss.Elements("channel") _ Select Titel = channel.Element("title").Value, _ Beschreibung = channel.Element("description").Value ' LINQ Abfrage auf ein Image der Webseite Dim img = From channelimage In rss.Elements("channel").Elements("image") _ Select ImageP = channelimage.Element("url").Value ' LINQ Abfrage auf die Items des Feeds Dim items = From item In rss.Descendants("item") _ Where Date.Parse(item.Element("pubDate").Value) > Date.Now.AddDays(-m_SkipDays) _ Select Titel = item.Element("title").Value, _ Link = item.Element("link").Value, _ Beschreibung = item.Element("description").Value, _ Datum = Date.Parse(item.Element("pubDate").Value) _ Order By Datum Descending ' HTML aus den LINQ Abfragen generieren Dim sb As New StringBuilder sb.AppendFormat("<html><body style={0}background-color: {1}; " & _ "color: {2}; font-family: {3}; font-size: {4};{0}>{5}", _ ControlChars.Quote, ColorTranslator.ToHtml(m_BackColor), _ ColorTranslator.ToHtml(m_ForeColor), _ m_FontName, m_FontSize, ControlChars.CrLf) ' Header erstellen sb.Append("<h2>") If Not String.IsNullOrEmpty(img(0)) Then sb.AppendFormat("<img src={0}{1}{0} style={0}float:right; margin:5px;{0}>", _ ControlChars.Quote, img(0)) End If sb.AppendFormat("{0}</h2>{1}<hr />{2}", _ Info(0).Titel, Info(0).Beschreibung, ControlChars.CrLf) ' Items erstellen For Each p In items ' Alternativer Link Aufruf in einem neuen Browser-Fenster 'sb.AppendFormat("<p><a href={0}{1}{0} target={0}_blank{0}>{2}</a><br />", _ sb.AppendFormat("<p><a href={0}{1}{0}>{2}</a><br />", _ ControlChars.Quote, p.Link, p.Titel) sb.AppendFormat("{0}</p><p>{1}</p><hr />{2}", _ p.Datum, p.Beschreibung, ControlChars.CrLf) Next sb.AppendLine("</body></html>") ' Event in die aufrufende Form feuern und den HTMLStream übergeben, ' jedoch nur dann, wenn sich der Stream geändert hat. If Not OldStream.Equals(sb.ToString) Then RaiseEvent RSSReceived(Me, New RSSReceivedEventArgs(sb.ToString)) OldStream = sb.ToString End If End If End Sub End Class In unserem VB2008er Demoprojekt zeigen wir Ihnen, wie die Klasse in der Anwendung genutzt werden kann. Viel Erfolg! |