高效阅读:使用C#实现RSS和Atom订阅

在信息爆炸的时代,我们需要一种高效的方式来获取感兴趣的内容,并及时了解最新的动态。RSS和Atom订阅正是这样一种工具,它们允许我们订阅我们喜欢的网站、博客或新闻源,以便将最新的内容推送到我们的阅读器。本文将向您展示如何使用C#编程语言实现RSS和Atom订阅,帮助您更高效地阅读并获取所需信息。

下面正式开始订阅过程 (文章末尾附带完整代码):

  1. 引入命名空间和创建接口:
    首先,在代码开头引入System.Xml命名空间,它提供了XML文档处理的相关类和方法。然后,定义一个接口IFeedParser,该接口包含一个Parse方法,用于解析订阅源并返回内容。
using System.Xml;
  1. 实现AtomFeedParser:
    接下来,我们创建AtomFeedParser类,它实现了IFeedParser接口,并重写了Parse方法。在该方法中,我们使用HttpClient类来下载订阅源,并使用XmlDocument类加载XML文档。我们还使用XmlNamespaceManager类来处理XML命名空间,并使用XPath表达式选择所需的节点。然后,我们遍历每个节点,提取标题、链接、摘要、内容和发布时间等信息,并将其封装为FeedItem对象。最后,将所有的FeedItem对象添加到列表中,并返回该列表。
public class AtomFeedParser : IFeedParser
{
    public async Task<List<FeedItem>> Parse(string url)
    {
        var feedItems = new List<FeedItem>();
        var httpClient = new HttpClient();
        var feed = await httpClient.GetStringAsync(url);
        var xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(feed);
        var nsManager = new XmlNamespaceManager(xmlDoc.NameTable);
        nsManager.AddNamespace("atom", "http://www.w3.org/2005/Atom");
        var entries = xmlDoc.SelectNodes("//atom:entry", nsManager);
        foreach (XmlNode entry in entries!)
        {
            var title = entry.SelectSingleNode("atom:title", nsManager)?.InnerText;
            var link = entry.SelectSingleNode("atom:link", nsManager)?.Attributes!["href"]!.Value;
            var summary = entry.SelectSingleNode("atom:summary", nsManager)?.InnerText;
            var content = entry.SelectSingleNode("atom:content", nsManager)?.InnerText;
            var published = entry.SelectSingleNode("atom:published", nsManager)?.InnerText;
            feedItems.Add(new FeedItem
            {
                Title = title, Link = link, Content = content, Summary = summary, Published = published
            });
        }

        return feedItems;
    }
}
  1. 实现RssFeedParser:
    类似地,我们创建RssFeedParser类,也实现了IFeedParser接口,并重写了Parse方法。在这个方法中,我们使用与AtomFeedParser类似的逻辑来解析RSS订阅源。
public class RssFeedParser : IFeedParser
{
    public async Task<List<FeedItem>> Parse(string url)
    {
        var feedItems = new List<FeedItem>();
        var httpClient = new HttpClient();
        var feed = await httpClient.GetStringAsync(url);
        var xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(feed);
        var nsManager = new XmlNamespaceManager(xmlDoc.NameTable);
        nsManager.AddNamespace("rss", "http://rss2.org/schema/");
        nsManager.AddNamespace("content", "http://purl.org/rss/1.0/modules/content/");
        var entries = xmlDoc.SelectNodes("//rss/channel/item", nsManager);
        foreach (XmlNode entry in entries!)
        {
            var title = entry.SelectSingleNode("./title", nsManager)?.InnerText;
            var link = entry.SelectSingleNode("./link", nsManager)?.InnerText;
            var summary = entry.SelectSingleNode("./description", nsManager)?.InnerText;
            var content = entry.SelectSingleNode("./content:encoded", nsManager)?.InnerText;
            var published = entry.SelectSingleNode("./pubDate", nsManager)?.InnerText;
            feedItems.Add(new FeedItem
            {
                Title = title, Link = link, Content = content, Summary = summary, Published = published
            });
        }

        return feedItems;
    }
}
  1. 创建FeedItem类:
    接下来,我们创建FeedItem类,用于表示订阅项的各个属性,如标题、链接、内容、摘要和发布时间。
public class FeedItem
{
    public string? Title;
    public string? Link;
    public string? Content;
    public string? Summary;
    public string? Published;
}
  1. 创建辅助方法CreateFeedParser
  private static IFeedParser CreateFeedParser(string type)
  {
      if (type.Contains("atom"))
          return new AtomFeedParser();
      else if (type.Contains("rss"))
          return new RssFeedParser();
      throw new ArgumentException("Invalid feed URL");
  }

在这个辅助方法中,我们根据传入的类型参数选择创建适当的IFeedParser实例,即AtomFeedParserRssFeedParser

  1. 编写主程序测试功能:
    最后,我们在Main方法中调用ParseFeed方法,传入一个订阅源的URL。这里我们选择了一个示例URL(我的博客:https://shiyu.dev),并使用了RSS作为类型参数。然后,我们通过foreach循环遍历返回的FeedItem列表,并输出每个订阅项的标题。
public static class Program
{
    private static IFeedParser CreateFeedParser(string type)
    {
        if (type.Contains("atom"))
            return new AtomFeedParser();
        else if (type.Contains("rss"))
            return new RssFeedParser();

        throw new ArgumentException("Invalid feed URL");
    }

    public static async Task Main()
    {
        var test = CreateFeedParser("rss");
        var res = await test.Parse("https://shiyu.dev/rss/");
        foreach (var item in res)
        {
            // 输出订阅到的标题
            Console.WriteLine(item.Title);
        }
    }
}

在这里插入图片描述
至此,我们已经完成了使用C#实现RSS和Atom订阅的代码。

附带完整代码:

using System.Xml;

namespace CSharp
{
    public interface IFeedParser
    {
        Task<List<FeedItem>> Parse(string url);
    }


    public class AtomFeedParser : IFeedParser
    {
        public async Task<List<FeedItem>> Parse(string url)
        {
            var feedItems = new List<FeedItem>();
            var httpClient = new HttpClient();
            var feed = await httpClient.GetStringAsync(url);
            var xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(feed);
            var nsManager = new XmlNamespaceManager(xmlDoc.NameTable);
            nsManager.AddNamespace("atom", "http://www.w3.org/2005/Atom");
            var entries = xmlDoc.SelectNodes("//atom:entry", nsManager);
            foreach (XmlNode entry in entries!)
            {
                var title = entry.SelectSingleNode("atom:title", nsManager)?.InnerText;
                var link = entry.SelectSingleNode("atom:link", nsManager)?.Attributes!["href"]!.Value;
                var summary = entry.SelectSingleNode("atom:summary", nsManager)?.InnerText;
                var content = entry.SelectSingleNode("atom:content", nsManager)?.InnerText;
                var published = entry.SelectSingleNode("atom:published", nsManager)?.InnerText;
                feedItems.Add(new FeedItem
                {
                    Title = title, Link = link, Content = content, Summary = summary, Published = published
                });
            }

            return feedItems;
        }
    }


    public class RssFeedParser : IFeedParser
    {
        public async Task<List<FeedItem>> Parse(string url)
        {
            var feedItems = new List<FeedItem>();
            var httpClient = new HttpClient();
            var feed = await httpClient.GetStringAsync(url);
            var xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(feed);
            var nsManager = new XmlNamespaceManager(xmlDoc.NameTable);
            nsManager.AddNamespace("rss", "http://rss2.org/schema/");
            nsManager.AddNamespace("content", "http://purl.org/rss/1.0/modules/content/");
            var entries = xmlDoc.SelectNodes("//rss/channel/item", nsManager);
            foreach (XmlNode entry in entries!)
            {
                var title = entry.SelectSingleNode("./title", nsManager)?.InnerText;
                var link = entry.SelectSingleNode("./link", nsManager)?.InnerText;
                var summary = entry.SelectSingleNode("./description", nsManager)?.InnerText;
                var content = entry.SelectSingleNode("./content:encoded", nsManager)?.InnerText;
                var published = entry.SelectSingleNode("./pubDate", nsManager)?.InnerText;
                feedItems.Add(new FeedItem
                {
                    Title = title, Link = link, Content = content, Summary = summary, Published = published
                });
            }

            return feedItems;
        }
    }

    public class FeedItem
    {
        public string? Title;
        public string? Link;
        public string? Content;
        public string? Summary;
        public string? Published;
    }

    public static class Program
    {
        private static IFeedParser CreateFeedParser(string type)
        {
            if (type.Contains("atom"))
                return new AtomFeedParser();
            else if (type.Contains("rss"))
                return new RssFeedParser();

            throw new ArgumentException("Invalid feed URL");
        }

        public static async Task Main()
        {
            var test = CreateFeedParser("rss");
            var res = await test.Parse("https://shiyu.dev/rss/");
            foreach (var item in res)
            {
                // 输出订阅到的标题
                Console.WriteLine(item.Title);
            }
        }
    }
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值