Récemment, j'ai créé un générateur de flux RSS pour une application ASP.NET. D'abord, vous dérivez de XmlWriter
. Ensuite, vous créez la page qui hébergera les flux. Là vous allez:
public enum RssElements
{
Rss, Channel, Title, Description, Link, Copyright, Generator, Item, PubDate
}
public enum RssAttributes
{
Version
}
/// <summary>
/// RSS writer that emits RSS feeds.
/// </summary>
public class RssWriter : XmlWriter
{
private XmlWriter writer;
private Stream objStream;
#region Constructor
public RssWriter (Stream stream)
{
objStream = stream;
writer = XmlWriter.Create (objStream);
}
#endregion
#region Stream Related Operations
public override void Close()
{
objStream.Close();
writer.Close();
}
public override void Flush()
{
writer.Flush();
}
#endregion
#region Writing Elements
public void WriteStartElement (RssElements element)
{
string elementName = "";
switch (element)
{
case RssElements.Channel:
elementName = "channel";
break;
case RssElements.Copyright:
elementName = "copyright";
break;
case RssElements.Description:
elementName = "description";
break;
case RssElements.Generator:
elementName = "generator";
break;
case RssElements.Item:
elementName = "item";
break;
case RssElements.Link:
elementName = "link";
break;
case RssElements.PubDate:
elementName = "pubDate";
break;
case RssElements.Rss:
elementName = "rss";
break;
case RssElements.Title:
elementName = "title";
break;
}
writer.WriteStartElement (elementName);
}
public void WriteElementString (RssElements element, string value)
{
string elementName = "";
switch (element)
{
case RssElements.Channel:
elementName = "channel";
break;
case RssElements.Copyright:
elementName = "copyright";
break;
case RssElements.Description:
elementName = "description";
break;
case RssElements.Generator:
elementName = "generator";
break;
case RssElements.Item:
elementName = "item";
break;
case RssElements.Link:
elementName = "link";
break;
case RssElements.PubDate:
elementName = "pubDate";
break;
case RssElements.Rss:
elementName = "rss";
break;
case RssElements.Title:
elementName = "title";
break;
}
writer.WriteElementString (elementName, value);
}
public override void WriteEndElement() { writer.WriteEndElement(); }
#endregion
#region Writing Attributes
public void WriteStartAttribute (RssAttributes attb)
{
if (attb == RssAttributes.Version)
{
writer.WriteStartAttribute ("version");
}
}
public void WriteAttributeString (RssAttributes attb, string value)
{
if (attb == RssAttributes.Version)
{
writer.WriteAttributeString ("version", value);
}
}
public override void WriteEndAttribute() { writer.WriteEndAttribute(); }
#endregion
#region Writing Data
public override void WriteCData (string text) { writer.WriteCData (text); }
public override void WriteChars (char [] buffer, int index, int count) { writer.WriteChars (buffer, index, count); }
public override void WriteComment (string text) { writer.WriteComment (text); }
public override void WriteWhitespace (string ws) { writer.WriteWhitespace (ws); }
public override void WriteString (string text) { writer.WriteString (text); }
#endregion
#region Document
public override void WriteStartDocument() { writer.WriteStartDocument(); }
public override void WriteStartDocument (bool standalone) { writer.WriteStartDocument (standalone); }
public override void WriteEndDocument() { writer.WriteEndDocument(); }
#endregion
#region Not Implemented Methods
void ThrowException() { throw new Exception ("The method or operation is not implemented."); }
public override string LookupPrefix (string ns) { ThrowException(); return ""; }
public override void WriteBase64 (byte [] buffer, int index, int count) { ThrowException(); }
public override void WriteCharEntity (char ch) { ThrowException(); }
public override void WriteStartElement (string prefix, string localName, string ns) { ThrowException(); }
public override WriteState WriteState
{
get { throw new Exception ("The method or operation is not implemented."); }
}
public override void WriteSurrogateCharEntity (char lowChar, char highChar) { ThrowException(); }
public override void WriteEntityRef (string name) { ThrowException(); }
public override void WriteFullEndElement() { ThrowException(); }
public override void WriteProcessingInstruction (string name, string text) { ThrowException(); }
public override void WriteRaw (string data) { ThrowException(); }
public override void WriteRaw (char [] buffer, int index, int count) { ThrowException(); }
public override void WriteStartAttribute (string prefix, string localName, string ns) { ThrowException(); }
public override void WriteDocType (string name, string pubid, string sysid, string subset) { ThrowException(); }
#endregion
}
Puis vous créez la page d'hôte. C'est une page vide; tout le travail est fait dans l'événement Page_Load. Ci-dessous, je vous donne l'événement Page_Load. Remarque: vous pouvez remplacer les objets de base de données par vos objets métier.
protected void Page_Load (object sender, EventArgs e)
{
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.ContentType = "text/xml";
RssWriter writer = new RssWriter (Response.OutputStream);
writer.WriteStartElement (RssElements.Rss);
writer.WriteAttributeString (RssAttributes.Version, "2.0");
writer.WriteStartElement (RssElements.Channel);
writer.WriteElementString (RssElements.Title, "XYZ corp.com");
writer.WriteElementString (RssElements.Link, "http://www.yourdomain.com");
writer.WriteElementString (RssElements.Description, "Latest news from XYZ corp");
writer.WriteElementString (RssElements.Copyright, "Copyright (C) XYZ corp. All rights reserved.");
writer.WriteElementString (RssElements.Generator, "XYZ corp XML RSS Generator");
DataTable newsTable = NewsAccess.GetLatestNewsByDate (false);
if (newsTable.Rows.Count > 0) {
for (int i = 0; i < newsTable.Rows.Count; ++i)
{
string id = newsTable.Rows [i] ["LatestNewsID"].ToString();
string subject = newsTable.Rows [i] ["Subject"].ToString();
string description = newsTable.Rows [i] ["Description"].ToString();
bool publicView = newsTable.Rows [i] ["PublicView"].ToString() == "True" ? true : false;
if (!publicView)
continue;
//string details = newsTable.Rows [i] ["Details"].ToString();
DateTime dt = DateTime.Parse (newsTable.Rows [i] ["DateCreated"].ToString());
string date = dt.ToString ("R");
writer.WriteStartElement (RssElements.Item);
writer.WriteElementString (RssElements.Title, subject);
writer.WriteElementString (RssElements.Link, "http://www.yourdomain.com/Contents/News/newsarticle.aspx?id=" + id.ToString());
writer.WriteElementString (RssElements.Description, description);
writer.WriteElementString (RssElements.PubDate, date);
writer.WriteEndElement();
}
}
writer.WriteEndElement();
writer.WriteEndElement();
writer.Close();
Response.End();
}
J'espère que cela a aidé un peu.
J'aime ça. Je suis nouveau à la génération de RSS et ceci peut être une question stupide, mais cela pose-t-il des problèmes pour certains lecteurs RSS parce qu'il ne spécifie pas les espaces de noms XML? Quand je regarde des échantillons RSS, je vois assez souvent des espaces de noms liés dans http://www.xml.com/pub/a/2002/12/18/dive-into-xml.html Parfois, par exemple, mon Firefox "live" signets "ne reconnaîtra pas les types simplifiés de flux. Je suis curieux de savoir si vous ciblez un large éventail de lecteurs avec ceci ou un spécifique? –
Vous pouvez ajouter un espace de noms à l'auteur: http://msdn.microsoft.com/fr-fr/library/cfche0ka.aspx – ScottE