2012-06-25 163 views
4

如何使用我的WordPress博客的RSS源以在我的主頁上顯示我的最新博客文章?我碰到了下面的一段代碼來做到這一點:在ASP.NET中使用WordPress RSS源

Function GetRSSFeed(strURL as String) as DataTable 
    'Get the XML data 
    Dim reader as XmlTextReader = New XmlTextReader(strURL) 

    'return a new DataSet 
    Dim ds as DataSet = New DataSet() 
    ds.ReadXml(reader)  
    Return ds.Tables(2) 
    End Function 

但它在這一行出現了錯誤:與以下錯誤「ds.ReadXml(閱讀器)」:

A column named 'comments' already belongs to this DataTable. 

也許它不因爲這個代碼是從2003年開始工作的嗎?有沒有人有工作代碼示例?提前謝謝了!

回答

17

您可以使用LINQ to XML來讀取WordPress RSS feed。

首先獲取Feed。製作一個Uri實例。

var rssFeed = new Uri("http://cgeers.com/feed/"); 

然後執行GET請求。

var request = (HttpWebRequest) WebRequest.Create(rssFeed); 
request.Method = "GET"; 
var response = (HttpWebResponse) request.GetResponse(); 

獲取響應流並讀取它以下載該提要的內容。

using (var reader = new StreamReader(response.GetResponseStream())) 
{ 
    var feedContents = reader.ReadToEnd(); 
    //... 
} 

仍然在上面的using語句中使用LINQ to XML來解析下載的內容並提取您需要的信息。

var document = XDocument.Parse(feedContents); 

var posts = (from p in document.Descendants("item") 
      select new 
      { 
       Title = p.Element("title").Value, 
       Link = p.Element("link").Value, 
       Comments = p.Element("comments").Value, 
       PubDate = DateTime.Parse(p.Element("pubDate").Value) 
      }).ToList(); 

現在您可以迭代結果。

foreach(var post in posts) 
{ 
    Console.WriteLine(post.Title); 
    Console.WriteLine(post.Link); 
    Console.WriteLine(post.Comments); 
    Console.WriteLine(post.PubDate); 
} 

這裏我只是用一個匿名類型來捕獲輸出,但隨時創建自己的博文類或類似的東西,你可以在LINQ查詢使用。

我習慣了C#,所以這就是爲什麼我在我的回覆中使用它。但你可以輕鬆地轉換它。有一些您可以使用的online converters

關於DataSet的問題(我個人不會用它來實現這個問題),它是由具有同名節點的項目(博客文章)引起的。

例如:

<comments>...</comments> 
<slash:comments>5</slash:comments> 

當然,第二個有不同的命名空間(斜線),但數據集的的ReadXml(...)方法不關心的命名空間。它試圖創建名爲「comments」的第二列。這就是爲什麼你會得到例外。

如果需要,您仍然可以使用DataSet/DataTable。如上所示,只需使用LINQ to XML從提要中提取數據即可。

然後創建一個DataSet並向它添加一個新表。

var dataSet = new DataSet(); 
var blog = new DataTable("Blog"); 
blog.Columns.Add("Title", typeof(string)); 
blog.Columns.Add("Link", typeof(string)); 
blog.Columns.Add("Comments", typeof(string)); 
dataSet.Tables.Add(blog); 

遍歷提取數據,並將其添加到DataTable:

foreach (var post in posts) 
{ 
    var newRow = blog.NewRow(); 
    newRow["Title"] = post.Title; 
    newRow["Link"] = post.Link; 
    newRow["Comments"] = post.Comments; 

    blog.Rows.Add(newRow); 
} 

瞧,我們現在不再依靠DataSet的的ReadXml(...)方法固定您的問題。下載Feed,提取您感興趣的數據並堅持下去。

+0

謝謝!這比使用數據表好得多。有沒有辦法按日期對帖子進行排序(只是爲了確保最新的帖子位於頂部)? – Zishan

+1

@Christophe:自.NET 3.5以來,我們已將RSS構建到基類庫中。您可以使用兩行代碼加載RSS。 –

+0

@Zhan:當然,只需要對IEnumerable進行排序(例如posts.OrderByDescending(p => p.PubDate);) –

3

我與內置類的RSS/Atom開始:SyndicationFeed

using (XmlReader reader = XmlReader.Create(url)) 
{ 
    return SyndicationFeed.Load(reader); 
} 
5

我將在System.ServiceModel.Syndication命名空間開始,有類直接操縱的RSS源。特別是,這看起來很有希望:

XmlReader reader = XmlReader.Create("http://your.uri.here/feed.xml"); 
SyndicationFeed feed = SyndicationFeed.Load(reader); 

然後探索SyndicationFeed類,特別是Items集合應該包含RSS條目。

0

這只是@Christophe格爾斯的轉換爲VB偉大的解決方案,作爲一個函數:

Protected Function getWordPressFeed(ByVal strUrl As String) As DataTable 

    Dim rssFeed = New Uri(strUrl) 
    Dim request = DirectCast(WebRequest.Create(rssFeed), HttpWebRequest) 
    request.Method = "GET" 
    Dim response = DirectCast(request.GetResponse(), HttpWebResponse) 
    Dim feedContents As String 
    Using reader = New StreamReader(response.GetResponseStream()) 
     feedContents = reader.ReadToEnd() 
    End Using 
    Dim document = XDocument.Parse(feedContents) 

    Static Dim dcNamespace As XNamespace 
    dcNamespace = "http://purl.org/dc/elements/1.1/" 

    Dim posts = (From p In document.Descendants("item") Select New With { _ 
     Key .Title = p.Element("title").Value, _ 
     Key .Link = p.Element("link").Value, _ 
     Key .Author = p.Element(dcNamespace + "creator").Value, _ 
     Key .Description = p.Element("description").Value, _ 
     Key .PubDate = DateTime.Parse(p.Element("pubDate").Value) _ 
    }).ToList() 

    Dim dataSet = New DataSet() 
    Dim blog = New DataTable("Blog") 
    blog.Columns.Add("Title", GetType(String)) 
    blog.Columns.Add("Link", GetType(String)) 
    blog.Columns.Add("Description", GetType(String)) 
    blog.Columns.Add("Author", GetType(String)) 
    blog.Columns.Add("PubDate", GetType(DateTime)) 

    dataSet.Tables.Add(blog) 
    For Each post In posts 
     Dim newRow = blog.NewRow() 
     newRow("Title") = post.Title 
     newRow("Link") = post.Link 
     newRow("Description") = post.Description 
     newRow("Author") = post.Author 
     newRow("PubDate") = post.PubDate 
     blog.Rows.Add(newRow) 
    Next 

    Return blog 

End Function 
0

這是我用我的WordPress的Feed閱讀器。

private async void ReadFeed() { 
    var rssFeed = new Uri("http://truestrengthmd.com/category/blog/feed"); 

    var request = (HttpWebRequest)WebRequest.Create(rssFeed); 
    request.Method = "GET"; 
    var _response = await request.GetResponseAsync(); 
    var response = (HttpWebResponse)_response; 

    using (var reader = new StreamReader(response.GetResponseStream())) 
    { 
     var feedContents = reader.ReadToEnd(); 

     var document = XDocument.Parse(feedContents); 

     var posts = (from p in document.Descendants("item") 
        select new 
        { 
         Title = p.Element("title").Value 
        }).ToList(); 

     foreach (var post in posts) 
     { 
      Debug.WriteLine(post.Title); 
     } 
    } 
} 
0

你可以使用我的圖書館這樣的:wprssapi.marcogriep.de

的代碼只有幾行。很容易做到:

//Get an Instance of Wordpress Controller (Singleton) 
       WordPressFeedController wp = WordPressFeedController.Instance; 

       //Load all the RSS Articles 
       wp.LoadRSS("http://www.its-all-about.de/rss"); 

       //Get the Newest Article (Check Docs for other functions) 
       var rssItem = wp.GetNewestItem(); 

       this.label1.Text = rssItem.Title; 

       //Text Only, Remove all the HTML Tags - Limit too 300 Chars 
       this.richTextBox1.Text = wp.RemoveHTMLFromText(rssItem.Summary.Substring(0, 300)) + "..."; 

       //Open RSS Article on Button Click 
       this.button1.Click += (s, e) => { 
        Process.Start(rssItem.Id); 
       };