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

使用 XmlTextWriter 创建有效的 RSS 2.0 文档

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.73/5 (25投票s)

2003年8月11日

3分钟阅读

viewsIcon

214291

downloadIcon

1754

使用 XmlTextWriter 创建有效的 RSS 2.0 文档

背景

随着 RSS 和网络日志的兴起,我决定为我的网站创建一个简单的 RSS Feed。在此过程中,我遇到了一些我认为应该与我的 CP 同仁分享的特殊情况。如果您想查看此代码的实际运行效果,请查看

我首先找到一个 RSS 2.0 规范,可以在这里找到。我不会解释规范,因为他们自己比我做得更好。查看之后,我开始寻找现有的示例。我找到了一些,但它们都使用StringBuilder来生成实际的 XML。这可能会导致无效字符等问题,所以我决定使用XmlTextWriter撰写一篇文章。

实现

一旦决定使用XmlTextWriter,我就直接开始编写代码。我首先编写了一个方法来编写 RSS 文档的前言或标题。

public XmlTextWriter WriteRSSPrologue(XmlTextWriter writer)
{ 
  writer.WriteStartDocument();
  writer.WriteStartElement("rss");
  writer.WriteAttributeString("version","2.0");
  writer.WriteAttributeString("xmlns:blogChannel",
     "http://backend.userland.com/blogChannelModule");
  writer.WriteStartElement("channel");
  writer.WriteElementString("title","Simple RSS Document");
  writer.WriteElementString("link","http://www.danielbright.net/");
  writer.WriteElementString("description",
     "A simple RSS document generated using XMLTextWriter");
  writer.WriteElementString("copyright","Copyright 2002-2003 Dan Bright");
  writer.WriteElementString("generator","RSSviaXmlTextWriter v1.0"); 

return writer;
}

如您所见,您可以将要使用的XmlTextWriter实例传递给此方法,它将返回已写入标题信息的实例。非常简单。

现在我们继续向文档中添加<item>。我再次查看了规范。一切看起来都很简单,直到我看到<pubDate>元素。

"RSS 中的所有日期时间都符合RFC 822的日期和时间规范,但年份可以使用两位数字或四位数字表示(建议使用四位数字)。"

这让我很困惑。我花了大约 20 分钟尝试自己编写符合 RFC 822 的DateTime,然后灵光一闪:谷歌。快速搜索后,我发现Martin Gudgin也遇到了同样的问题,并找到了解决方案。看来(如果我阅读了DateTime.ToString()文档,我就会知道)传递r参数将为我们提供所需的 RFC 822 日期。不错。

public XmlTextWriter AddRSSItem(XmlTextWriter writer, 
         string sItemTitle, string sItemLink, 
         string sItemDescription)
{
  writer.WriteStartElement("item");
  writer.WriteElementString("title",sItemTitle);
  writer.WriteElementString("link",sItemLink);
  writer.WriteElementString("description",sItemDescription);
  writer.WriteElementString("pubDate", DateTime.Now.ToString("r"));
  writer.WriteEndElement();

  return writer;
}

这次我们将XmlTextWriter以及我们希望创建的<item>的实际部分传递给方法。

注意:它将使用DateTime.Now为我们生成<pubDate>元素,但这只是一个示例。如果您将此文档加载到 RSS 聚合器中,则每次请求文档时项目都会显示为新的,从而使聚合器迅速充满重复条目。

现在我们必须清理 RSS 文档,再次传递要使用的XmlTextWriter

public XmlTextWriter WriteRSSClosing(XmlTextWriter writer)
{
  writer.WriteEndElement();
  writer.WriteEndElement();
  writer.WriteEndDocument();

  return writer;
}

一旦我们建立了这个基础,我们就开始创建 RSS 文档。

这是我遇到的第二个问题。我一直在使用StringWriter作为缓冲区来存储我的XmlTextWriter。这很好,除了StringWriter被硬编码为使用 UTF-16 编码。这根本不是问题,除非您尝试使用 Internet Explorer 打开我们的 RSS 文档。IE 用于显示 XML 的内部样式表显然不喜欢 UTF-16,并且不会显示文档。

另一个谷歌搜索让我找到了Roy Osherove 的网络日志上的一篇帖子,讨论了这件事。非常感谢 Stephane 指出在这种情况下使用MemoryStream是正确的做法。

private void Page_Load(object sender, System.EventArgs e)
{
  XmlTextWriter writer = new XmlTextWriter(Response.OutputStream, 
    System.Text.Encoding.UTF8);  


 
  WriteRSSPrologue(writer);
  
  AddRSSItem(writer,"Item Title","http://test.com", "This is a test item"); 
  AddRSSItem(writer,"Item 2 Title", "http://test.com/blabla.aspx">http://test.com/blabla.aspx, 

    "This is the second test item"); 
  AddRSSItem(writer,"<b>Item 2 Title</b>", "http://test.com/blabla.aspx">http://test.com/blabla.aspx, 

    "This is the second test item");

  WriteRSSClosing(writer);
  writer.Flush();

  writer.Close(); 
  
  Response.ContentEncoding = System.Text.Encoding.UTF8; 
  Response.ContentType = "text/xml";  
  Response.Cache.SetCacheability(HttpCacheability.Public);

  Response.End();
}

就是这样。现在这将输出有效的 RSS,即使传递了无效字符,这也要归功于XmlTextWriter

历史

  • 更新:2003 年 9 月 15 日
    • 我已经使用了Response.OutputStream代替下面的评论中建议的MemoryStream。这修复了我发现的两个小错误。以前,如果列出超过 5 个项目,IE 使用的样式表将无法正确呈现页面。此问题已解决。此外,如果描述字段以 CDATA 编写,IE 也无法正确呈现页面。此问题也已解决。
    • 我已向AddRSSItem添加了一个重载,允许您通过boolean将描述作为CDATA 写入。
© . All rights reserved.