2011-10-24 26 views
3

我想檢測,如果飼料已經改變的最好方式,我能想到的唯一辦法是散列XML文檔的內容和比較,到最後Feed的散列。C#什麼是計算一個xml飼料的哈希

我使用的XmlReader,因爲SyndicationFeed使用它,所以idealy我不想除非飼料已更新加載聯合供稿。

XmlReader reader = XmlReader.Create("http://www.extremetech.com/feed"); 
SyndicationFeed feed = SyndicationFeed.Load(reader); 
+0

哈希碰撞的後果是什麼?也就是說,假設兩個文件具有相同的散列值。什麼是可能發生的最糟糕的事情? –

+1

我做了一些更多的測試,如果這是你的確切的feed,這個feed中有一些評論會定期更改,即使非註釋xml標籤永遠不會改變,所以我認爲散列方法根本不會起作用 – MerickOWA

+0

@MerickOWA我想我會只是去使用那就是在SyndicationItem的ID ..如果提要標題或文章被編輯它不會是一個問題可能會更容易:)而這樣! – superlogical

回答

2

哈希方法不會在這種情況下工作,由於一些服務器端增加了一個XML註釋:不是哈希和存儲的哈希您只需保持LastUpdatedTime的跟蹤,並定期把它比作最新LastUpdatedTime的即使實際的Feed沒有變化,它也經常非常頻繁地進行緩存。

有一兩件事你可以做哪些工作該飼料是利用HTTP條件請求向服務器給你的數據只有當它的,因爲你最後一次請求的時候居然被修改。

例如:

你就會有一個全局/成員變量從您的飼料

var lastModified = DateTime.MinValue; 

舉行的最後修改日期時間則每次你會做類似下面

的請求
var request = (HttpWebRequest)WebRequest.Create("http://www.extremetech.com/feed"); 
    request.IfModifiedSince = lastModified; 
    try { 

     using (var response = (HttpWebResponse)request.GetResponse()) { 

     lastModified = response.LastModified; 

     using (var stream = response.GetResponseStream()) { 

      //*** parsing the stream 
      var reader = XmlReader.Create(stream); 
      SyndicationFeed feed = SyndicationFeed.Load(reader); 
      } 
     } 
     } 
    catch (WebException e) { 
     var response = (HttpWebResponse)e.Response; 
     if (response.StatusCode != HttpStatusCode.NotModified) 
     throw; // rethrow an unexpected web exception 
     } 
+1

+1中的ID來正確使用HTTP。您還可以在響應中使用EXPIRES標頭(如果存在)和feed中的元數據(上次更新日期,更新週期和更新頻率),以指導您何時/應多久檢查一次更新。 –

3

爲什麼不只是檢查飼料的LastUpdatedTime?這是一種告訴你是否有新東西的內置方式。

using System; 
using System.ServiceModel.Syndication; 
using System.Xml; 

public class MyClass 
{ 
    private static DateTime _lastFeedTime = new DateTime(2011, 10, 10); 

    public static void Main() 
    { 
     XmlReader reader = XmlReader.Create("http://www.extremetech.com/feed"); 
     SyndicationFeed feed = SyndicationFeed.Load(reader); 

     if (feed.LastUpdatedTime.LocalDateTime > _lastFeedTime) 
     { 
      _lastFeedTime = feed.LastUpdatedTime.LocalDateTime; 

      // load feed... 
     } 
    } 
} 
+0

是的,我認爲,但我只是不知道如何可靠,將考慮一些飼料可能不會更新該值。但是,那麼我可能會完全錯誤:) Wordpress總是玩這個好嗎?我想要索引的大多數Feed都是基於WordPress的 – superlogical

+0

LastUpdatedTime完全不可靠,因爲它取決於服務器協作。 – usr

+0

首先給DateTime事一個嘗試。除非必須,否則不要假設和解決問題。是的,你依賴於符合標準但始終發生的第三方。我想不出比LastUpdatedTime更符合的更有用的元數據。違規應該導致體罰。 ;-) –

3

如果你真的想要去的散列方式,你可以做到以下幾點:

var client = new WebClient(); 

var content = client.DownloadData("http://www.extremetech.com/feed"); 

var hash = MD5.Create().ComputeHash(content); 
var hashString = Convert.ToBase64String(hash); 

// you can then compare hashes and if changed load it this way 
XmlReader reader = XmlReader.Create(new MemoryStream(content)); 

當然會這樣你會發現在內容中的任何改變,哪怕是一丁點。

恕我直言,以最好的方式是無論如何裝載飼料和散列只是文章的內容,你可以哈希任何字符串是這樣的:

var toHash = "string to hash"; 

var hash = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(toHash); 
var hashString = Convert.ToBase64String(hash); 

希望這有助於。