<? xml version = "1.0" ? >
< rss version = "2.0" >
< channel >
< title > Liftoff News </ title >
< link > liftoff.msfc.nasa.gov </ link >
< description > Liftoff to Space Exploration. </ description >
')
< item >
< title > Star City </ title >
< link > liftoff.msfc.nasa.gov/news/2003/news-starcity.asp </ link >
< description >
How do Americans get ready to work
International Space Station? They take a crash course in culture, language
and the protocol at Russia's Star City.
</ description >
< pubDate > Tue, 03 Jun 2003 09:39:21 GMT </ pubDate >
</ item >
< item >
< title > Space Exploration </ title >
< link > liftoff.msfc.nasa.gov </ link >
< description >
Sky watchers in Europe, Asia, and parts of Alaska and Canada
on Saturday, May 31st.
</ description >
< pubDate > Fri, 30 May 2003 11:06:42 GMT </ pubDate >
</ item >
</ channel >
</ rss >
using
System;
using System.Collections.Generic;
using System.Text;
namespace RssReader
{
class RssItem
{
}
}
class RssItem
{
public String title; // record header
public
String link; // link to
full text
public String description; // record description
}
///
/// Constructor to fill the record
///
/// <param
name = "ItemTag"> xml tag for reading
public
RssItem ( XmlNode ItemTag)
{
//
view all post tags
foreach ( XmlNode xmlTag in
ItemTag.ChildNodes)
{
// check the tag name if
corresponds to one of the specified,
// then in
the corresponding property of the object is written the contents of the tag
switch (xmlTag.Name)
{
case "title" :
{
this .Title = xmlTag.InnerText;
break ;
}
case
"Description" :
{
this .Description = xmlTag.InnerText;
break ;
}
case
"Link" :
{
this .Link
= xmlTag.InnerText;
break ;
}
}
}
}
using
System.Xml;
using
System;
using System.Collections.Generic;
using System.Text;
namespace
RssReader
{
class rssItems
{
}
}
///
/// Check for the existence of the specified
item in list
///
/// object to compare
/// true if there is an object in the list, otherwise
false
new
public
bool Contains ( RssItem Item)
{
foreach ( RssItem itemForCheck in this )
{
//
Compare record headers
if
(Item.Title == itemForCheck.Title)
{
// found
coincidence. return the truth
return
true ;
}
}
//
no matches found. we return the box
return
false ;
}
///
/// Get an entry from the list by its
header
///
/// record title
/// If the record exists, it is returned
otherwise, it returns null
public RssItem GetItem ( String Title)
{ foreach ( RssItem itemForCheck in this )
{
//
Compare the record header with the query.
if
(Item.Title == Title)
{
// found a match.
return the found record
return
itemForCheck;
}
}
// no matches found.
return null ;
}
using
System;
using System.Collections.Generic;
using System.Text;
namespace RssReader
{
class RssFeed
{
}
}
class RssFeed
{
public String Title;
// channel header
public
String Description; //
description of the canal
public
String link; // link to
channel related website
public
RssItems Items; // list of channel entries
}
///
/// Constructor for filling data
channel
///
/// Channel Address
public
RssFeed ( String Url)
{
//
We initialize the list of records
Items = new
RssItems ();
// Create a reader to read Rss from
specified address
XmlTextReader
xmlTextReader = New XmlTextReader (Url);
// create a new xml document to write to it
RSS feed
XmlDocument xmlDoc = New
XmlDocument ();
try
{
// load the RSS into the document using the reader
xmlDoc.Load (xmlTextReader);
// close reader for
uselessness
xmlTextReader.Close ();
//
since all the RSS feed information is written between the tags,
// ship we get this thread.
XmlNode channelXmlNode = xmlDoc.GetElementsByTagName ( "channel" ) [0];
// if a
the branch exists, we begin to flood the properties of the object
// data from a branch
if
(channelXmlNode! = null )
{
// iterate all descendants of the tag
foreach ( XmlNode
channelNode in channelXmlNode.ChildNodes)
{
// if the name of the descendant tag is of interest to us, then
write his data
// to a specific
object property
switch
(channelNode.Name)
{
case
"Title" :
{
Title =
channelNode.InnerText;
break ;
}
case "description" :
{
Description =
channelNode.InnerText;
break ;
}
case "link" :
{
Link = channelNode.InnerText;
break ;
}
case "item" : // if the name of the tag being checked is item, then
{
// create a new tag from this
write object
Rss <span
lang = "en-us"> Item channelItem = new
RssItem (channelNode);
// and add it to
list of channel entries
Items.Add (channelItem);
break ;
}
}
}
}
else
//
if no tag is found in the resulting file, then we throw an exception
{
throw New Exception ( "Error in XML. Channel description not found!" );
}
}
// If the channel url is not specified correctly, then throw it away.
source unreachable exception
catch
(System.Net.WebException ex)
{
if (ex.Status
== System.Net.WebExceptionStatus.NameResolutionFailure)
throw new Exception ( "Unable to connect to the specified source. \ r \ n" +
Url);
else throw
ex;
}
// if the RSS address was specified
local path that does not exist yet,
//
then throw the corresponding exception
catch
(System.IO.FileNotFoundException)
{
throw New
Exception ( "File" + Url + "
not found! ” );
}
// well and lastly, we catch everything
the remaining exceptions, and pass them on as is
catch (Exception ex)
{
throw
ex;
}
finally
{
//
close the reader
xmlTextReader.Close ();
}
}
Final stage
Now, all that's left to do is write the code for the click event handlers.
“update” buttons and selecting an item in ListView , as well as adding a global variable CurrentFeed, in which the loaded channel will be stored:
//
Global variable storing channel data
Rssfeed
CurrentFeed;
// processing of clicking on the "Update" button
private void btRefresh_Click ( object sender, EventArgs
e)
{
// Check if the address is set
if (! String .IsNullOrEmpty (tbUrl.Text))
{
// Clear the ListView before adding new data
lvNews.Clear ();
// Initialize the channel
CurrentFeed = new RssFeed (tbUrl.Text);
foreach ( Rss <span
lang = "en-us"> Item feedItem in
CurrentFeed.Items)
{
// create an item to display in the ListView
ListViewItem listViewItem = new ListViewItem (feedItem.Title);
// set his name
listViewItem.Name = feedItem.Title;
// put it in the listview
lvNews.Items.Add (listViewItem);
}
}
}
// Processing the change of item selection in the ListView
private void lvNews_SelectedIndexChanged ( object sender, EventArgs
e)
{
// get the news associated with the selected ListViewItem
if (lvNews.SelectedItems.Count> 0
&& // check that something is really selected
CurrentFeed! = Null
&& // check that the channel is initialized
CurrentFeed.Items.Count> 0
// check the existence of records in the channel
)
{
// display the full text of the selected entry
wbDescription.DocumentText =
CurrentFeed.Items.GetItem (lvNews.SelectedItems [0] .Text) .Description;
}
}
Conclusion
As a result, we got a simple RSS reader that can read standard 2.0 feeds.
In the next article I will try to tell you how to make our classes more
universal, as well as you can organize the storage of the history of visited
tapes.
Download the source of the written reader here .
PS: constructive criticism, as well as suggestions and suggestions are welcome.
Source: https://habr.com/ru/post/27443/