首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 動態生成 RSS 2.0 Feed:XmlDocument 與 XmlTextWriter 兩種方案

     編輯:關於C語言

RSS 2.0 結構速覽

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel>
    <title>頻道標題</title>
    <link>網站鏈接</link>
    <description>頻道描述</description>
    <item>...</item> <!-- 多篇文章 -->
  </channel>
</rss>

方案一:XmlDocument (DOM 模型)

適合需要在內存中構建、修改、查詢 XML 結構的場景。


public void GenerateRssWithXmlDocument(HttpResponse Response)
{
    XmlDocument doc = new XmlDocument();
    
    // XML 聲明
    XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "utf-8", "yes");
    doc.AppendChild(decl);
    
    // 可選:關聯 CSS 樣式表
    XmlProcessingInstruction pi = doc.CreateProcessingInstruction(
        "xml-stylesheet", "type=\"text/xsl\" href=\"rss.xsl\"");
    doc.AppendChild(pi);
    
    // 根元素
    XmlElement rss = doc.CreateElement("rss");
    rss.SetAttribute("version", "2.0");
    doc.AppendChild(rss);
    
    // channel
    XmlElement channel = doc.CreateElement("channel");
    rss.AppendChild(channel);
    
    // 輔助方法:添加文本節點
    void AddTextElement(string name, string text)
    {
        XmlElement el = doc.CreateElement(name);
        el.AppendChild(doc.CreateTextNode(text));
        channel.AppendChild(el);
    }
    
    // 輔助方法:添加 CDATA 節點
    void AddCDataElement(string name, string cdata)
    {
        XmlElement el = doc.CreateElement(name);
        el.AppendChild(doc.CreateCDataSection(cdata));
        channel.AppendChild(el);
    }
    
    AddTextElement("title", "搜狐焦點新聞");
    AddTextElement("link", "https://www.sohu.com");
    AddCDataElement("description", "即時報道國內外時政大事,解讀環球焦點事件");
    
    // 模擬數據源
    DataTable dt = GetNewsData(); // 你的數據訪問邏輯
    foreach (DataRow row in dt.Rows)
    {
        XmlElement item = doc.CreateElement("item");
        
        AddItemChild(item, "title", row["Title"].ToString());
        AddItemChild(item, "link", row["Url"].ToString());
        AddItemChild(item, "pubDate", Convert.ToDateTime(row["PubDate"]).ToString("R")); // RFC 1123
        AddItemChild(item, "description", row["Summary"].ToString());
        // 可選:guid, author, category, enclosure 等
        
        channel.AppendChild(item);
    }
    
    // 輸出
    Response.ContentType = "application/rss+xml";
    Response.ContentEncoding = Encoding.UTF8;
    using (XmlTextWriter writer = new XmlTextWriter(Response.OutputStream, Encoding.UTF8))
    {
        writer.Formatting = Formatting.Indented;
        doc.WriteTo(writer);
    }
}

void AddItemChild(XmlElement parent, string name, string text)
{
    XmlElement el = parent.OwnerDocument.CreateElement(name);
    el.AppendChild(parent.OwnerDocument.CreateTextNode(text));
    parent.AppendChild(el);
}

方案二:XmlTextWriter (流式寫入,高性能)

不構建內存樹,直接流式輸出,內存佔用極低,適合大數據量 Feed。


public void GenerateRssWithWriter(HttpResponse Response)
{
    Response.ContentType = "application/rss+xml";
    Response.ContentEncoding = Encoding.UTF8;
    
    using (XmlTextWriter writer = new XmlTextWriter(Response.OutputStream, Encoding.UTF8))
    {
        writer.Formatting = Formatting.Indented;
        writer.Indentation = 2;
        
        writer.WriteStartDocument();
        writer.WriteComment($"Generated at {DateTime.UtcNow:R}");
        
        writer.WriteStartElement("rss");
        writer.WriteAttributeString("version", "2.0");
        
        writer.WriteStartElement("channel");
        
        writer.WriteElementString("title", "搜狐焦點新聞");
        writer.WriteElementString("link", "https://www.sohu.com");
        writer.WriteElementString("description", "即時報道國內外時政大事,解讀環球焦點事件");
        // 或使用 CDATA: writer.WriteCData("內容");
        
        DataTable dt = GetNewsData();
        foreach (DataRow row in dt.Rows)
        {
            writer.WriteStartElement("item");
            writer.WriteElementString("title", row["Title"].ToString());
            writer.WriteElementString("link", row["Url"].ToString());
            writer.WriteElementString("pubDate", Convert.ToDateTime(row["PubDate"]).ToString("R"));
            writer.WriteElementString("description", row["Summary"].ToString());
            writer.WriteEndElement(); // item
        }
        
        writer.WriteEndElement(); // channel
        writer.WriteEndElement(); // rss
        writer.WriteEndDocument();
    }
}

關鍵最佳實踐

要點說明
日期格式必須符合 RFC 822/1123,如 DateTime.ToString("R") 輸出 Mon, 25 Dec 2023 12:00:00 GMT
特殊字符WriteElementString/CreateTextNode 自動轉義 & < >;包含 HTML 片段請用 WriteCData/CreateCDataSection
編碼聲明統一使用 UTF-8,HTTP Header 與 XML 聲明保持一致
GUID每個 <item> 應有唯一 <guid isPermaLink="true">,利於聚合器去重
緩存策略設置 Response.Cache.SetCacheability(HttpCacheability.Public) + SetMaxAge,減少頻繁請求
Content-Type標準 MIME: application/rss+xml 或 application/xml

保存為文件 vs 直接輸出


// 保存文件
using (XmlTextWriter writer = new XmlTextWriter(Server.MapPath("feed.xml"), Encoding.UTF8)) { ... }

// 直接輸出 (如上示例)
using (XmlTextWriter writer = new XmlTextWriter(Response.OutputStream, Encoding.UTF8)) { ... }

現代替代:SyndicationFeed (.NET 3.5+)

System.ServiceModel.Syndication.SyndicationFeed 提供高級對象模型,自動處理格式、編碼、Atom/RSS 双格式輸出:


var feed = new SyndicationFeed("標題", "描述", new Uri("https://site.com"));
feed.Items = newsList.Select(n => new SyndicationItem(n.Title, n.Summary, new Uri(n.Url)));
using (var writer = XmlWriter.Create(Response.OutputStream, new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true }))
    feed.SaveAsRss20(writer); // 或 SaveAsAtom10

總結

XmlDocument 適合需要操作 XML 結構的場景;XmlTextWriter 性能最優,適合高吞吐輸出;現代項目首選 SyndicationFeed 簡化開發。無論哪種方式,嚴格遵循 RSS 2.0 規範(日期、編碼、轉義、GUID)是生成兼容性良好 Feed 的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved