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

读取 Windows Phone 7 上的 RSS 项目

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (5投票s)

2011 年 2 月 3 日

Ms-PL

2分钟阅读

viewsIcon

27782

如何在 Windows Phone 7 上读取 RSS 项目

以下是我编写的一个实用类,用于在 Windows Phone 7 的 Silverlight 应用程序中异步读取 RSS 项目。

我将介绍它是如何编写的,以及如何使用它。 在本文末尾,您可以找到一个包含所有代码的示例应用程序。

如何读取 RSS?

添加辅助程序集

我们需要做的第一件事是添加对程序集 System.ServiceModel.Syndication.dll 的引用,该程序集包含可以解析 RSS 源的类。

此程序集是 Silverlight 3 SDK 的一部分。 它不是 Windows Phone 7 SDK 的一部分,但在此处使用没有问题。 您可以在 %ProgramFiles%\Microsoft SDKs\Silverlight\v3.0\Libraries\Client\System.ServiceModel.Syndication.dll 下找到该文件。

Add Reference dialog

您将收到以下警告,请忽略它,它能正常工作。

Adding a reference to a Silverlight assembly may lead to unexpected application behavior. Do you want to continue?

定义 RssItem

在开始之前,让我们定义一个模型类,用于封装单个 RSS 项目的数据。

我们的 RssItem 类将包含以下属性:Title(标题)、Summary(摘要)、PublishedDate(发布日期)和 Url(网址)。 此外,我提供了一个 PlainSummary 属性,它将包含 RSS 项目的纯文本版本。 通常,摘要包含我们只想忽略的 HTML 标签,因此 PlainSummary 可以解决这个问题。

/// <summary>
/// Model for RSS item
/// </summary>
public class RssItem
{
    /// <summary>
    /// Initializes a new instance of the <see cref="RssItem"/> class.
    /// </summary>
    /// <param name="title">The title.</param>
    /// <param name="summary">The summary.</param>
    /// <param name="publishedDate">The published date.</param>
    /// <param name="url">The URL.</param>
    public RssItem(string title, string summary, string publishedDate, string url)
    {
        Title = title;
        Summary = summary;
        PublishedDate = publishedDate;
        Url = url;

        // Get plain text from html
        PlainSummary = HttpUtility.HtmlDecode(Regex.Replace(summary, "<[^>]+?>", ""));
    }

    /// <summary>
    /// Gets or sets the title.
    /// </summary>
    /// <value>The title.</value>
    public string Title { get; set; }

    /// <summary>
    /// Gets or sets the summary.
    /// </summary>
    /// <value>The summary.</value>
    public string Summary { get; set; }

    /// <summary>
    /// Gets or sets the published date.
    /// </summary>
    /// <value>The published date.</value>
    public string PublishedDate { get; set; }

    /// <summary>
    /// Gets or sets the URL.
    /// </summary>
    /// <value>The URL.</value>
    public string Url { get; set; }

    /// <summary>
    /// Gets or sets the plain summary.
    /// </summary>
    /// <value>The plain summary.</value>
    public string PlainSummary { get; set; }
}

实现 RSS 服务

RSS 服务将获取 RSS 源 URL 作为参数。 此外,由于我们希望我们的类异步工作,我们将接受更多委托作为参数

  • Action<IEnumerable<RssItem>> onGetRssItemsCompleted,当 RSS 项目准备好进行处理时将调用它。
  • Action<Exception> onError,如果在获取 RSS 项目时发生错误将调用它。
  • Action onFinally,无论是否发生异常,都将始终调用它。 将其视为常见的 try-catch 块的 finally 部分。

因此,该方法签名将是

public static void GetRssItems(string rssFeed, 
    Action<IEnumerable<RssItem>> onGetRssItemsCompleted = null, 
    Action<Exception> onError = null, Action onFinally = null)

要获取源 XML,我们将使用 WebClient

WebClient webClient = new WebClient();

// register on download complete event
webClient.OpenReadCompleted += delegate(object sender, OpenReadCompletedEventArgs e)
{
    ...
};

webClient.OpenReadAsync(new Uri(rssFeed));

实际的 RSS 解析是使用来自我们的辅助程序集的 SyndicationFeed 类完成的

// convert rss result to model
List<RssItem> rssItems = new List<RssItem>();
Stream stream = e.Result;
XmlReader response = XmlReader.Create(stream);
SyndicationFeed feeds = SyndicationFeed.Load(response);
foreach (SyndicationItem f in feeds.Items)
{
    RssItem rssItem = new RssItem(f.Title.Text, f.Summary.Text, f.PublishDate.ToString(), 
        f.Links[0].Uri.AbsoluteUri);
    rssItems.Add(rssItem);
}

其余代码用于处理不同的委托:onCompletedonErroronFinally。 我在此处提供完整的方法

/// <summary>
/// Gets the RSS items.
/// </summary>
/// <param name="rssFeed">The RSS feed.</param>
/// <param name="onGetRssItemsCompleted">The on get RSS items completed.</param>
/// <param name="onError">The on error.</param>
public static void GetRssItems(string rssFeed, 
    Action<IEnumerable<RssItem>> onGetRssItemsCompleted = null, 
    Action<Exception> onError = null, Action onFinally = null)
{
    WebClient webClient = new WebClient();

    // register on download complete event
    webClient.OpenReadCompleted += delegate(object sender, OpenReadCompletedEventArgs e)
    {
        try
        {
            // report error
            if (e.Error != null)
            {
                if (onError != null)
                {
                    onError(e.Error);
                }
                return;
            }

            // convert rss result to model
            List<RssItem> rssItems = new List<RssItem>();
            Stream stream = e.Result;
            XmlReader response = XmlReader.Create(stream);
            SyndicationFeed feeds = SyndicationFeed.Load(response);
            foreach (SyndicationItem f in feeds.Items)
            {
                RssItem rssItem = new RssItem(f.Title.Text, f.Summary.Text, 
                    f.PublishDate.ToString(), f.Links[0].Uri.AbsoluteUri);
                rssItems.Add(rssItem);
            }

            // notify completed callback
            if (onGetRssItemsCompleted != null)
            {
                onGetRssItemsCompleted(rssItems);
            }
        }
        finally
        {
            // notify finally callback
            if (onFinally != null)
            {
                onFinally();
            }
        }
    };

    webClient.OpenReadAsync(new Uri(rssFeed));
}

使用 RSS 服务

使用该类非常简单,只需将 URL 作为第一个参数提供,并提供一个委托以获取“完成”通知即可。

private void Button_Click(object sender, RoutedEventArgs e)
{
    RssService.GetRssItems(
        WindowsPhoneBlogPosts,
        (items) => { listbox.ItemsSource = items; },
        (exception) => { MessageBox.Show(exception.Message); },
        null
        );
}

可以从 此处 下载示例应用程序。

image

注意:此代码最初作为 Windows Phone 开发者培训工具包 中“使用 Pivot 和 Panorama 控件”实验室的一部分发布,我为 Microsoft 编写了该工具包。

暂时就到这里,
Arik Poznanski

© . All rights reserved.