RSS Reader

7/31/2008
I talked in the past about creating an RSS feed and how it's a fairly easy thing to do. One thing that I didn't really cover (and it might be something that you would like to do), is reading in an RSS feed. Perhaps you want to create an aggregator or blog roll or something. In my case, I was simply creating a better code base for creating feeds and decided I might as well be able to read them as well.

Document.cs

   1: /*
   2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
   3: 
   4: Permission is hereby granted, free of charge, to any person obtaining a copy
   5: of this software and associated documentation files (the "Software"), to deal
   6: in the Software without restriction, including without limitation the rights
   7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   8: copies of the Software, and to permit persons to whom the Software is
   9: furnished to do so, subject to the following conditions:
  10: 
  11: The above copyright notice and this permission notice shall be included in
  12: all copies or substantial portions of the Software.
  13: 
  14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20: THE SOFTWARE.*/
  21:  
  22: #region Usings
  23: using System.Collections.Generic;
  24: using System.Text;
  25: using System.Xml;
  26: #endregion
  27:  
  28: namespace Utilities.FileFormats.RSSHelper
  29: {
  30:     /// <summary>
  31:     /// RSS document class
  32:     /// </summary>
  33:     public class Document
  34:     {
  35:         #region Constructors
  36:  
  37:         /// <summary>
  38:         /// Constructor
  39:         /// </summary>
  40:         public Document()
  41:         {
  42:         }
  43:  
  44:         /// <summary>
  45:         /// Constructor
  46:         /// </summary>
  47:         /// <param name="Location">Location of the RSS feed to load</param>
  48:         public Document(string Location)
  49:         {
  50:             XmlDocument Document = new XmlDocument();
  51:             Document.Load(Location);
  52:             Load(Document);
  53:         }
  54:  
  55:         /// <summary>
  56:         /// Constructor
  57:         /// </summary>
  58:         /// <param name="Document">XML document containing an RSS feed</param>
  59:         public Document(XmlDocument Document)
  60:         {
  61:             Load(Document);
  62:         }
  63:  
  64:         #endregion
  65:  
  66:         #region Private Variables
  67:  
  68:         private List<Channel> _Channels = null;
  69:  
  70:         #endregion
  71:  
  72:         #region Properties
  73:  
  74:         /// <summary>
  75:         /// Channels for the RSS feed
  76:         /// </summary>
  77:         public List<Channel> Channels
  78:         {
  79:             get
  80:             {
  81:                 if (_Channels == null)
  82:                 {
  83:                     _Channels = new List<Channel>();
  84:                 }
  85:                 return _Channels;
  86:             }
  87:             set { _Channels = value; }
  88:         }
  89:  
  90:         #endregion
  91:  
  92:         #region Public Overridden Functions
  93:  
  94:         /// <summary>
  95:         /// string representation of the RSS feed.
  96:         /// </summary>
  97:         /// <returns>An rss formatted string</returns>
  98:         public override string ToString()
  99:         {
 100:             StringBuilder DocumentString = new StringBuilder("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<rss xmlns:itunes=\"http://www.itunes.com/dtds/podcast-1.0.dtd\" xmlns:media=\"http://search.yahoo.com/mrss/\" version=\"2.0\">\r\n");
 101:             foreach (Channel CurrentChannel in Channels)
 102:             {
 103:                 DocumentString.Append(CurrentChannel.ToString());
 104:             }
 105:             DocumentString.Append("</rss>");
 106:             return DocumentString.ToString();
 107:         }
 108:  
 109:         #endregion
 110:  
 111:         #region Public Functions
 112:  
 113:         /// <summary>
 114:         /// Copies one document's channels to another
 115:         /// </summary>
 116:         /// <param name="CopyFrom">RSS document to copy from</param>
 117:         public void Copy(Document CopyFrom)
 118:         {
 119:             foreach (Channel CurrentChannel in CopyFrom.Channels)
 120:             {
 121:                 Channels.Add(CurrentChannel);
 122:             }
 123:         }
 124:  
 125:         #endregion
 126:  
 127:         #region Private Functions
 128:  
 129:         private void Load(XmlDocument Document)
 130:         {
 131:             XmlNamespaceManager NamespaceManager = new XmlNamespaceManager(Document.NameTable);
 132:             XmlNodeList Nodes = Document.DocumentElement.SelectNodes("./channel", NamespaceManager);
 133:             foreach (XmlNode Element in Nodes)
 134:             {
 135:                 Channels.Add(new Channel((XmlElement)Element));
 136:             }
 137:             if (Channels.Count == 0)
 138:             {
 139:                 Nodes = Document.DocumentElement.SelectNodes(".//channel", NamespaceManager);
 140:                 foreach (XmlNode Element in Nodes)
 141:                 {
 142:                     Channels.Add(new Channel((XmlElement)Element));
 143:                 }
 144:                 List<Item> Items = new List<Item>();
 145:                 Nodes = Document.DocumentElement.SelectNodes(".//item", NamespaceManager);
 146:                 foreach (XmlNode Element in Nodes)
 147:                 {
 148:                     Items.Add(new Item((XmlElement)Element));
 149:                 }
 150:                 if (Channels.Count > 0)
 151:                 {
 152:                     Channels[0].Items = Items;
 153:                 }
 154:             }
 155:         }
 156:  
 157:         #endregion
 158:     }
 159: }

Channel.cs

   1: /*
   2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
   3: 
   4: Permission is hereby granted, free of charge, to any person obtaining a copy
   5: of this software and associated documentation files (the "Software"), to deal
   6: in the Software without restriction, including without limitation the rights
   7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   8: copies of the Software, and to permit persons to whom the Software is
   9: furnished to do so, subject to the following conditions:
  10: 
  11: The above copyright notice and this permission notice shall be included in
  12: all copies or substantial portions of the Software.
  13: 
  14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20: THE SOFTWARE.*/
  21:  
  22: #region Usings
  23: using System;
  24: using System.Collections.Generic;
  25: using System.Text;
  26: using System.Xml;
  27:  
  28: #endregion
  29:  
  30: namespace Utilities.FileFormats.RSSHelper
  31: {
  32:     /// <summary>
  33:     /// Channel item for RSS feeds
  34:     /// </summary>
  35:     public class Channel
  36:     {
  37:         #region Constructor
  38:  
  39:         /// <summary>
  40:         /// Constructor
  41:         /// </summary>
  42:         public Channel()
  43:         {
  44:         }
  45:  
  46:         /// <summary>
  47:         /// Constructor
  48:         /// </summary>
  49:         /// <param name="Element">XML representation of the channel</param>
  50:         public Channel(XmlElement Element)
  51:         {
  52:             if (!Element.Name.Equals("channel", StringComparison.CurrentCultureIgnoreCase))
  53:                 throw new ArgumentException("Element is not a channel");
  54:             XmlNamespaceManager NamespaceManager = new XmlNamespaceManager(Element.OwnerDocument.NameTable);
  55:             XmlNode Node = Element.SelectSingleNode("./title", NamespaceManager);
  56:             if (Node != null)
  57:             {
  58:                 Title = Node.InnerText;
  59:             }
  60:             Node = Element.SelectSingleNode("./link", NamespaceManager);
  61:             if (Node != null)
  62:             {
  63:                 Link = Node.InnerText;
  64:             }
  65:             Node = Element.SelectSingleNode("./description", NamespaceManager);
  66:             if (Node != null)
  67:             {
  68:                 Description = Node.InnerText;
  69:             }
  70:             Node = Element.SelectSingleNode("./copyright", NamespaceManager);
  71:             if (Node != null)
  72:             {
  73:                 Copyright = Node.InnerText;
  74:             }
  75:             Node = Element.SelectSingleNode("./language", NamespaceManager);
  76:             if (Node != null)
  77:             {
  78:                 Language = Node.InnerText;
  79:             }
  80:             Node = Element.SelectSingleNode("./webmaster", NamespaceManager);
  81:             if (Node != null)
  82:             {
  83:                 WebMaster = Node.InnerText;
  84:             }
  85:             Node = Element.SelectSingleNode("./pubdate", NamespaceManager);
  86:             if (Node != null)
  87:             {
  88:                 PubDate = DateTime.Parse(Node.InnerText);
  89:             }
  90:             XmlNodeList Nodes = Element.SelectNodes("./category", NamespaceManager);
  91:             foreach (XmlNode TempNode in Nodes)
  92:             {
  93:                 Categories.Add(RSS.StripIllegalCharacters(TempNode.InnerText));
  94:             }
  95:             Node = Element.SelectSingleNode("./docs", NamespaceManager);
  96:             if (Node != null)
  97:             {
  98:                 Docs = Node.InnerText;
  99:             }
 100:             Node = Element.SelectSingleNode("./ttl", NamespaceManager);
 101:             if (Node != null)
 102:             {
 103:                 TTL = int.Parse(Node.InnerText);
 104:             }
 105:             Node = Element.SelectSingleNode("./image/url", NamespaceManager);
 106:             if (Node != null)
 107:             {
 108:                 ImageUrl = Node.InnerText;
 109:             }
 110:             Nodes = Element.SelectNodes("./item", NamespaceManager);
 111:             foreach (XmlNode TempNode in Nodes)
 112:             {
 113:                 Items.Add(new Item((XmlElement)TempNode));
 114:             }
 115:         }
 116:  
 117:         #endregion
 118:  
 119:         #region Private Variables
 120:         private string _Title = string.Empty;
 121:         private string _Link = string.Empty;
 122:         private string _Description = string.Empty;
 123:         private string _Copyright = "Copyright " + DateTime.Now.ToString("yyyy") + ". All rights reserved.";
 124:         private string _Language = "en-us";
 125:         private string _webMaster = string.Empty;
 126:         private DateTime _pubDate = DateTime.Now;
 127:         private List<string> _Categories = null;
 128:         private string _Docs = "http://blogs.law.harvard.edu/tech/rss";
 129:         private string _Cloud = string.Empty;
 130:         private int _TTL = 5;
 131:         private string _ImageUrl = string.Empty;
 132:         private List<Item> _Items = null;
 133:         private bool _Explicit = false;
 134:         #endregion
 135:  
 136:         #region Properties
 137:         /// <summary>
 138:         /// Determines if this is explicit or not
 139:         /// </summary>
 140:         public bool Explicit
 141:         {
 142:             get
 143:             {
 144:                 return _Explicit;
 145:             }
 146:             set { _Explicit = value; }
 147:         }
 148:         /// <summary>
 149:         /// Items for this channel
 150:         /// </summary>
 151:         public List<Item> Items
 152:         {
 153:             get
 154:             {
 155:                 if (_Items == null)
 156:                 {
 157:                     _Items = new List<Item>();
 158:                 }
 159:                 return _Items;
 160:             }
 161:             set { _Items = value; }
 162:         }
 163:         /// <summary>
 164:         /// Title of the channel
 165:         /// </summary>
 166:         public string Title
 167:         {
 168:             get { return _Title; }
 169:             set { _Title = RSS.StripIllegalCharacters(value); }
 170:         }
 171:  
 172:         /// <summary>
 173:         /// Link to the website
 174:         /// </summary>
 175:         public string Link
 176:         {
 177:             get { return _Link; }
 178:             set { _Link = value; }
 179:         }
 180:  
 181:         /// <summary>
 182:         /// Description of the channel
 183:         /// </summary>
 184:         public string Description
 185:         {
 186:             get { return _Description; }
 187:             set { _Description = RSS.StripIllegalCharacters(value); }
 188:         }
 189:  
 190:         /// <summary>
 191:         /// Copyright info
 192:         /// </summary>
 193:         public string Copyright
 194:         {
 195:             get { return _Copyright; }
 196:             set { _Copyright = value; }
 197:         }
 198:  
 199:         /// <summary>
 200:         /// Language it is in
 201:         /// </summary>
 202:         public string Language
 203:         {
 204:             get { return _Language; }
 205:             set { _Language = value; }
 206:         }
 207:  
 208:         /// <summary>
 209:         /// Web Master info
 210:         /// </summary>
 211:         public string WebMaster
 212:         {
 213:             get { return _webMaster; }
 214:             set { _webMaster = value; }
 215:         }
 216:  
 217:         /// <summary>
 218:         /// Date the channel was published
 219:         /// </summary>
 220:         public DateTime PubDate
 221:         {
 222:             get { return _pubDate; }
 223:             set { _pubDate = value; }
 224:         }
 225:  
 226:         /// <summary>
 227:         /// Categories associated with this channel
 228:         /// </summary>
 229:         public List<string> Categories
 230:         {
 231:             get
 232:             {
 233:                 if (_Categories == null)
 234:                 {
 235:                     _Categories = new List<string>();
 236:                 }
 237:                 return _Categories;
 238:             }
 239:             set { _Categories = value; }
 240:         }
 241:  
 242:         /// <summary>
 243:         /// Document describing the file format
 244:         /// </summary>
 245:         public string Docs
 246:         {
 247:             get { return _Docs; }
 248:             set { _Docs = value; }
 249:         }
 250:  
 251:         /// <summary>
 252:         /// Cloud information
 253:         /// </summary>
 254:         public string Cloud
 255:         {
 256:             get { return _Cloud; }
 257:             set { _Cloud = value; }
 258:         }
 259:  
 260:         /// <summary>
 261:         /// Time to live... Amount of time between updates.
 262:         /// </summary>
 263:         public int TTL
 264:         {
 265:             get { return _TTL; }
 266:             set { _TTL = value; }
 267:         }
 268:  
 269:         /// <summary>
 270:         /// Url pointing to the image/logo associated with the channel
 271:         /// </summary>
 272:         public string ImageUrl
 273:         {
 274:             get { return _ImageUrl; }
 275:             set { _ImageUrl = value; }
 276:         }
 277:         #endregion
 278:  
 279:         #region Overridden Functions
 280:  
 281:         public override string ToString()
 282:         {
 283:             StringBuilder ChannelString = new StringBuilder();
 284:             ChannelString.Append("<channel>");
 285:             ChannelString.Append("<title>").Append(Title).Append("</title>\r\n");
 286:             ChannelString.Append("<link>").Append(Link).Append("</link>\r\n");
 287:             ChannelString.Append("<atom:link xmlns:atom=\"http://www.w3.org/2005/Atom\" rel=\"self\" href=\"").Append(Link).Append("\" type=\"application/rss).Append(xml\" />");
 288:  
 289:             ChannelString.Append("<description><![CDATA[").Append(Description).Append("]]></description>\r\n");
 290:             ChannelString.Append("<language>").Append(Language).Append("</language>\r\n");
 291:             ChannelString.Append("<copyright>").Append(Copyright).Append("</copyright>\r\n");
 292:             ChannelString.Append("<webMaster>").Append(WebMaster).Append("</webMaster>\r\n");
 293:             ChannelString.Append("<pubDate>").Append(PubDate.ToString("Ddd, dd MMM yyyy HH':'mm':'ss")).Append("</pubDate>\r\n");
 294:             ChannelString.Append("<itunes:explicit>").Append((Explicit ? "yes" : "no")).Append("</itunes:explicit>");
 295:             ChannelString.Append("<itunes:subtitle>").Append(Title).Append("</itunes:subtitle>");
 296:             ChannelString.Append("<itunes:summary><![CDATA[").Append(Description).Append("]]></itunes:summary>");
 297:  
 298:             foreach (string Category in Categories)
 299:             {
 300:                 ChannelString.Append("<category>").Append(Category).Append("</category>\r\n");
 301:                 ChannelString.Append("<itunes:category text=\"").Append(Category).Append("\" />\r\n");
 302:             }
 303:             ChannelString.Append("<docs>").Append(Docs).Append("</docs>\r\n");
 304:             ChannelString.Append("<ttl>").Append(TTL.ToString()).Append("</ttl>\r\n");
 305:             if (!string.IsNullOrEmpty(ImageUrl))
 306:             {
 307:                 ChannelString.Append("<image><url>").Append(ImageUrl).Append("</url>\r\n<title>").Append(Title).Append("</title>\r\n<link>").Append(Link).Append("</link>\r\n</image>\r\n");
 308:             }
 309:             foreach (Item CurrentItem in Items)
 310:             {
 311:                 ChannelString.Append(CurrentItem.ToString());
 312:             }
 313:             ChannelString.Append("</channel>\r\n");
 314:             return ChannelString.ToString();
 315:         }
 316:  
 317:         #endregion
 318:     }
 319: }

Item.cs

   1: /*
   2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
   3: 
   4: Permission is hereby granted, free of charge, to any person obtaining a copy
   5: of this software and associated documentation files (the "Software"), to deal
   6: in the Software without restriction, including without limitation the rights
   7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   8: copies of the Software, and to permit persons to whom the Software is
   9: furnished to do so, subject to the following conditions:
  10: 
  11: The above copyright notice and this permission notice shall be included in
  12: all copies or substantial portions of the Software.
  13: 
  14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20: THE SOFTWARE.*/
  21:  
  22: #region Usings
  23: using System;
  24: using System.Collections.Generic;
  25: using System.Text;
  26: using System.Xml;
  27: #endregion
  28:  
  29: namespace Utilities.FileFormats.RSSHelper
  30: {
  31:     /// <summary>
  32:     /// Item class for RSS feeds
  33:     /// </summary>
  34:     public class Item
  35:     {
  36:         #region Constructor
  37:  
  38:         /// <summary>
  39:         /// Constructor
  40:         /// </summary>
  41:         public Item()
  42:         {
  43:         }
  44:  
  45:         /// <summary>
  46:         /// Constructor
  47:         /// </summary>
  48:         /// <param name="Element">XML element containing the item content</param>
  49:         public Item(XmlElement Element)
  50:         {
  51:             if (!Element.Name.Equals("item", StringComparison.CurrentCultureIgnoreCase))
  52:                 throw new ArgumentException("Element is not an item");
  53:             XmlNamespaceManager NamespaceManager = new XmlNamespaceManager(Element.OwnerDocument.NameTable);
  54:             NamespaceManager.AddNamespace("media", "http://search.yahoo.com/mrss/");
  55:             XmlNode Node = Element.SelectSingleNode("./title", NamespaceManager);
  56:             if (Node != null)
  57:             {
  58:                 Title = Node.InnerText;
  59:             }
  60:             Node = Element.SelectSingleNode("./link", NamespaceManager);
  61:             if (Node != null)
  62:             {
  63:                 Link = Node.InnerText;
  64:             }
  65:             Node = Element.SelectSingleNode("./description", NamespaceManager);
  66:             if (Node != null)
  67:             {
  68:                 Description = Node.InnerText;
  69:             }
  70:             Node = Element.SelectSingleNode("./author", NamespaceManager);
  71:             if (Node != null)
  72:             {
  73:                 Author = Node.InnerText;
  74:             }
  75:             XmlNodeList Nodes = Element.SelectNodes("./category", NamespaceManager);
  76:             foreach (XmlNode TempNode in Nodes)
  77:             {
  78:                 Categories.Add(RSS.StripIllegalCharacters(TempNode.InnerText));
  79:             }
  80:             Node = Element.SelectSingleNode("./enclosure", NamespaceManager);
  81:             if (Node != null)
  82:             {
  83:                 Enclosure = new Enclosure((XmlElement)Node);
  84:             }
  85:             Node = Element.SelectSingleNode("./pubdate", NamespaceManager);
  86:             if (Node != null)
  87:             {
  88:                 PubDate = DateTime.Parse(Node.InnerText);
  89:             }
  90:             Node = Element.SelectSingleNode("./media:thumbnail", NamespaceManager);
  91:             if (Node != null)
  92:             {
  93:                 Thumbnail = new Thumbnail((XmlElement)Node);
  94:             }
  95:             Node = Element.SelectSingleNode("./guid", NamespaceManager);
  96:             if (Node != null)
  97:             {
  98:                 GUID = new GUID((XmlElement)Node);
  99:             }
 100:         }
 101:  
 102:         #endregion
 103:  
 104:         #region Private Variables
 105:         private string _Title = string.Empty;
 106:         private string _Link = string.Empty;
 107:         private string _Description = string.Empty;
 108:         private string _Author = string.Empty;
 109:         private Thumbnail _Thumbnail = null;
 110:         private List<string> _Categories = null;
 111:         private DateTime _pubDate = DateTime.Now;
 112:         private Enclosure _Enclosure = null;
 113:         #endregion
 114:  
 115:         #region Properties
 116:  
 117:         /// <summary>
 118:         /// GUID for the item
 119:         /// </summary>
 120:         public GUID GUID { get; set; }
 121:  
 122:         /// <summary>
 123:         /// Thumbnail information
 124:         /// </summary>
 125:         public Thumbnail Thumbnail
 126:         {
 127:             get
 128:             {
 129:                 if (_Thumbnail == null)
 130:                 {
 131:                     _Thumbnail = new Thumbnail();
 132:                 }
 133:                 return _Thumbnail;
 134:             }
 135:             set { _Thumbnail = value; }
 136:         }
 137:  
 138:         /// <summary>
 139:         /// Title of the item
 140:         /// </summary>
 141:         public string Title
 142:         {
 143:             get { return _Title; }
 144:             set { _Title = RSS.StripIllegalCharacters(value); }
 145:         }
 146:  
 147:         /// <summary>
 148:         /// Link to its location
 149:         /// </summary>
 150:         public string Link
 151:         {
 152:             get { return _Link; }
 153:             set { _Link = value; }
 154:         }
 155:  
 156:         /// <summary>
 157:         /// Description of the item
 158:         /// </summary>
 159:         public string Description
 160:         {
 161:             get { return _Description; }
 162:             set { _Description = RSS.StripIllegalCharacters(value); }
 163:         }
 164:  
 165:         /// <summary>
 166:         /// Author of the item
 167:         /// </summary>
 168:         public string Author
 169:         {
 170:             get { return _Author; }
 171:             set { _Author = RSS.StripIllegalCharacters(value); }
 172:         }
 173:  
 174:         /// <summary>
 175:         /// Categories associated with the item
 176:         /// </summary>
 177:         public List<string> Categories
 178:         {
 179:             get
 180:             {
 181:                 if (_Categories == null)
 182:                 {
 183:                     _Categories = new List<string>();
 184:                 }
 185:                 return _Categories;
 186:             }
 187:             set { _Categories = value; }
 188:         }
 189:  
 190:         /// <summary>
 191:         /// Date it was published
 192:         /// </summary>
 193:         public DateTime PubDate
 194:         {
 195:             get { return _pubDate; }
 196:             set { _pubDate = value; }
 197:         }
 198:  
 199:         /// <summary>
 200:         /// Enclosure (used for podcasting)
 201:         /// </summary>
 202:         public Enclosure Enclosure
 203:         {
 204:             get
 205:             {
 206:                 if (_Enclosure == null)
 207:                 {
 208:                     _Enclosure = new Enclosure();
 209:                 }
 210:                 return _Enclosure;
 211:             }
 212:             set { _Enclosure = value; }
 213:         }
 214:         #endregion
 215:  
 216:         #region Public Overridden Function
 217:  
 218:         /// <summary>
 219:         /// Outputs a string ready for RSS
 220:         /// </summary>
 221:         /// <returns>A string formatted for RSS</returns>
 222:         public override string ToString()
 223:         {
 224:             StringBuilder ItemString = new StringBuilder();
 225:             ItemString.Append("<item><title>").Append(Title).Append("</title>\r\n<link>")
 226:                 .Append(Link).Append("</link>\r\n<author>").Append(Author)
 227:                 .Append("</author>\r\n");
 228:             foreach (string Category in Categories)
 229:             {
 230:                 ItemString.Append("<category>").Append(Category).Append("</category>\r\n");
 231:             }
 232:             ItemString.Append("<pubDate>").Append(PubDate.ToString("r")).Append("</pubDate>\r\n");
 233:             ItemString.Append(Enclosure.ToString());
 234:             ItemString.Append(Thumbnail.ToString());
 235:             ItemString.Append("<description><![CDATA[").Append(Description).Append("]]></description>\r\n");
 236:             ItemString.Append(GUID.ToString());
 237:             ItemString.Append("<itunes:subtitle>").Append(Title).Append("</itunes:subtitle>");
 238:             ItemString.Append("<itunes:summary><![CDATA[").Append(Description).Append("]]></itunes:summary>");
 239:             ItemString.Append("</item>\r\n");
 240:             return ItemString.ToString();
 241:         }
 242:  
 243:         #endregion
 244:     }
 245: }

GUID.cs

   1: /*
   2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
   3: 
   4: Permission is hereby granted, free of charge, to any person obtaining a copy
   5: of this software and associated documentation files (the "Software"), to deal
   6: in the Software without restriction, including without limitation the rights
   7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   8: copies of the Software, and to permit persons to whom the Software is
   9: furnished to do so, subject to the following conditions:
  10: 
  11: The above copyright notice and this permission notice shall be included in
  12: all copies or substantial portions of the Software.
  13: 
  14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20: THE SOFTWARE.*/
  21:  
  22: #region Usings
  23: using System;
  24: using System.Xml;
  25: #endregion
  26:  
  27: namespace Utilities.FileFormats.RSSHelper
  28: {
  29:     /// <summary>
  30:     /// GUID info holder
  31:     /// </summary>
  32:     public class GUID
  33:     {
  34:         #region Constructor
  35:  
  36:         /// <summary>
  37:         /// Constructor
  38:         /// </summary>
  39:         public GUID()
  40:         {
  41:  
  42:         }
  43:         /// <summary>
  44:         /// Constructor
  45:         /// </summary>
  46:         /// <param name="Element">XML element holding info for the enclosure</param>
  47:         public GUID(XmlElement Element)
  48:         {
  49:             if (!Element.Name.Equals("guid", StringComparison.CurrentCultureIgnoreCase))
  50:                 throw new ArgumentException("Element is not a guid");
  51:             if (Element.Attributes["isPermaLink"] != null)
  52:             {
  53:                 PermaLink = Element.Attributes["isPermaLink"].Value;
  54:             }
  55:             GUIDText = Element.InnerText;
  56:         }
  57:  
  58:         #endregion
  59:  
  60:         #region Properties
  61:  
  62:         /// <summary>
  63:         /// Is this a perma link?
  64:         /// </summary>
  65:         public string PermaLink { get; set; }
  66:  
  67:         /// <summary>
  68:         /// GUID Text
  69:         /// </summary>
  70:         public string GUIDText { get; set; }
  71:  
  72:         #endregion
  73:  
  74:         #region Public Overridden Functions
  75:  
  76:         /// <summary>
  77:         /// to string item. Used for outputting the item to RSS.
  78:         /// </summary>
  79:         /// <returns>A string formatted for RSS output</returns>
  80:         public override string ToString()
  81:         {
  82:             if (!string.IsNullOrEmpty(GUIDText))
  83:             {
  84:                 return "<guid" + (string.IsNullOrEmpty(PermaLink) ? " IsPermaLink=" + PermaLink : " IsPermaLink='False'") + ">" + GUIDText + "</guid>\r\n";
  85:             }
  86:             return string.Empty;
  87:         }
  88:  
  89:         #endregion
  90:     }
  91: }

Enclosure.cs

   1: /*
   2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
   3: 
   4: Permission is hereby granted, free of charge, to any person obtaining a copy
   5: of this software and associated documentation files (the "Software"), to deal
   6: in the Software without restriction, including without limitation the rights
   7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   8: copies of the Software, and to permit persons to whom the Software is
   9: furnished to do so, subject to the following conditions:
  10: 
  11: The above copyright notice and this permission notice shall be included in
  12: all copies or substantial portions of the Software.
  13: 
  14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20: THE SOFTWARE.*/
  21:  
  22: #region Usings
  23: using System;
  24: using System.Xml;
  25: #endregion
  26:  
  27: namespace Utilities.FileFormats.RSSHelper
  28: {
  29:     /// <summary>
  30:     /// Enclosure class for RSS feeds (used for pod casting)
  31:     /// </summary>
  32:     public class Enclosure
  33:     {
  34:         #region Constructor
  35:  
  36:         /// <summary>
  37:         /// Constructor
  38:         /// </summary>
  39:         public Enclosure()
  40:         {
  41:  
  42:         }
  43:         /// <summary>
  44:         /// Constructor
  45:         /// </summary>
  46:         /// <param name="Element">XML element holding info for the enclosure</param>
  47:         public Enclosure(XmlElement Element)
  48:         {
  49:             if (!Element.Name.Equals("enclosure", StringComparison.CurrentCultureIgnoreCase))
  50:                 throw new ArgumentException("Element is not an enclosure");
  51:             if (Element.Attributes["url"] != null)
  52:             {
  53:                 Url = Element.Attributes["url"].Value;
  54:             }
  55:             if (Element.Attributes["length"] != null)
  56:             {
  57:                 Length = Element.Attributes["length"].Value;
  58:             }
  59:             if (Element.Attributes["type"] != null)
  60:             {
  61:                 Type = Element.Attributes["type"].Value;
  62:             }
  63:         }
  64:  
  65:         #endregion
  66:  
  67:         #region Private Variables
  68:         private string _Url = string.Empty;
  69:         private string _Length = string.Empty;
  70:         private string _Type = string.Empty;
  71:         #endregion
  72:  
  73:         #region Properties
  74:         /// <summary>
  75:         /// Location of the item
  76:         /// </summary>
  77:         public string Url
  78:         {
  79:             get { return _Url; }
  80:             set { _Url = value; }
  81:         }
  82:  
  83:         /// <summary>
  84:         /// Size in bytes
  85:         /// </summary>
  86:         public string Length
  87:         {
  88:             get { return _Length; }
  89:             set { _Length = value; }
  90:         }
  91:  
  92:         /// <summary>
  93:         /// File type
  94:         /// </summary>
  95:         public string Type
  96:         {
  97:             get { return _Type; }
  98:             set { _Type = value; }
  99:         }
 100:         #endregion
 101:  
 102:         #region Public Overridden Functions
 103:  
 104:         /// <summary>
 105:         /// to string item. Used for outputting the item to RSS.
 106:         /// </summary>
 107:         /// <returns>A string formatted for RSS output</returns>
 108:         public override string ToString()
 109:         {
 110:             if (!string.IsNullOrEmpty(_Url) && !string.IsNullOrEmpty(_Type) && !string.IsNullOrEmpty(_Length))
 111:             {
 112:                 return "<enclosure url=\"" + _Url + "\" length=\"" + _Length + "\" type=\"" + _Type + "\" />\r\n"
 113:                     + "<media:content url=\"" + _Url + "\" fileSize=\"" + _Length + "\" type=\"" + _Type + "\" />";
 114:  
 115:             }
 116:             return string.Empty;
 117:         }
 118:  
 119:         #endregion
 120:     }
 121: }

RSS.cs

   1: /*
   2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
   3: 
   4: Permission is hereby granted, free of charge, to any person obtaining a copy
   5: of this software and associated documentation files (the "Software"), to deal
   6: in the Software without restriction, including without limitation the rights
   7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   8: copies of the Software, and to permit persons to whom the Software is
   9: furnished to do so, subject to the following conditions:
  10: 
  11: The above copyright notice and this permission notice shall be included in
  12: all copies or substantial portions of the Software.
  13: 
  14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20: THE SOFTWARE.*/
  21:  
  22: namespace Utilities.FileFormats.RSSHelper
  23: {
  24:     /// <summary>
  25:     /// Utility class used by RSS classes.
  26:     /// </summary>
  27:     public static class RSS
  28:     {
  29:         #region Public Static Functions
  30:         /// <summary>
  31:         /// Strips illegal characters from RSS items
  32:         /// </summary>
  33:         /// <param name="Original">Original text</param>
  34:         /// <returns>string stripped of certain characters.</returns>
  35:         public static string StripIllegalCharacters(string Original)
  36:         {
  37:             Original = Original.Replace("&nbsp;", " ");
  38:             Original = Original.Replace("&#160;", string.Empty);
  39:             Original = Original.Trim().Replace("&", "and");
  40:             return Original;
  41:         }
  42:         #endregion
  43:     }
  44: }

Thumbnail.cs

   1: /*
   2: Copyright (c) 2010 <a href="http://www.gutgames.com">James Craig</a>
   3: 
   4: Permission is hereby granted, free of charge, to any person obtaining a copy
   5: of this software and associated documentation files (the "Software"), to deal
   6: in the Software without restriction, including without limitation the rights
   7: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   8: copies of the Software, and to permit persons to whom the Software is
   9: furnished to do so, subject to the following conditions:
  10: 
  11: The above copyright notice and this permission notice shall be included in
  12: all copies or substantial portions of the Software.
  13: 
  14: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20: THE SOFTWARE.*/
  21:  
  22: #region Usings
  23: using System;
  24: using System.Xml;
  25: #endregion
  26:  
  27: namespace Utilities.FileFormats.RSSHelper
  28: {
  29:     /// <summary>
  30:     /// Thumbnail info holder
  31:     /// </summary>
  32:     public class Thumbnail
  33:     {
  34:         #region Constructor
  35:  
  36:         /// <summary>
  37:         /// Constructor
  38:         /// </summary>
  39:         public Thumbnail()
  40:         {
  41:  
  42:         }
  43:         /// <summary>
  44:         /// Constructor
  45:         /// </summary>
  46:         /// <param name="Element">XML element holding info for the enclosure</param>
  47:         public Thumbnail(XmlElement Element)
  48:         {
  49:             if (!Element.Name.Equals("media:thumbnail", StringComparison.CurrentCultureIgnoreCase))
  50:                 throw new ArgumentException("Element is not a thumbnail");
  51:             if (Element.Attributes["url"] != null)
  52:             {
  53:                 Url = Element.Attributes["url"].Value;
  54:             }
  55:             if (Element.Attributes["width"] != null)
  56:             {
  57:                 Width = int.Parse(Element.Attributes["width"].Value);
  58:             }
  59:             if (Element.Attributes["height"] != null)
  60:             {
  61:                 Height = int.Parse(Element.Attributes["height"].Value);
  62:             }
  63:         }
  64:  
  65:         #endregion
  66:  
  67:         #region Private Variables
  68:  
  69:         private string _Url = string.Empty;
  70:         private int _Width = 1;
  71:         private int _Height = 1;
  72:  
  73:         #endregion
  74:  
  75:         #region Properties
  76:  
  77:         /// <summary>
  78:         /// Location of the item
  79:         /// </summary>
  80:         public string Url
  81:         {
  82:             get { return _Url; }
  83:             set { _Url = value; }
  84:         }
  85:  
  86:         /// <summary>
  87:         /// Image width
  88:         /// </summary>
  89:         public int Width
  90:         {
  91:             get { return _Width; }
  92:             set { _Width = value; }
  93:         }
  94:  
  95:         /// <summary>
  96:         /// Image height
  97:         /// </summary>
  98:         public int Height
  99:         {
 100:             get { return _Height; }
 101:             set { _Height = value; }
 102:         }
 103:  
 104:         #endregion
 105:  
 106:         #region Public Overridden Functions
 107:  
 108:         /// <summary>
 109:         /// to string item. Used for outputting the item to RSS.
 110:         /// </summary>
 111:         /// <returns>A string formatted for RSS output</returns>
 112:         public override string ToString()
 113:         {
 114:             if (!string.IsNullOrEmpty(_Url))
 115:             {
 116:                 return "<media:thumbnail url=\"" + _Url + "\" width=\"" + _Width.ToString() + "\" height=\"" + _Height + "\" />\r\n";
 117:             }
 118:             return string.Empty;
 119:         }
 120:  
 121:         #endregion
 122:     }
 123: }

Anyway, the code above can read in a well formatted RSS feed (that adheres to the 2.0 specification anyway). Allows for an easy way to combine feeds, output them, etc. All you need to do is create a Document object pointing to the location of the feed to read it in and use toString to output it back out. Anyway, download the code, leave feedback, and happy coding.



Comments