2011-10-24 9 views
3

フィードが変更されたかどうかを検出したいと思いますが、XML文書の内容をハッシュして最後のものと比較する方法が考えられますフィードのハッシュC#xmlフィードのハッシュを計算する最適な方法は何ですか

SyndicationFeedがそれを使用しているので、XmlReaderを使用しています。理想的には、フィードが更新されていない限り、シンジケーションフィードをロードしたくありません。

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

ハッシュの衝突の結果はどのようなものですか?つまり、2つのドキュメントが同じハッシュを持つとします。起こることができる最悪のことは何ですか? –

+1

これはあなたの正確なフィードである場合、いくつかのテストを行いましたが、コメントではないxmlタグが決して変更されないので、ハッシュアプ​​ローチはまったく動作しないと思う – MerickOWA

+0

@MerickOWA私はSyndicationItemにあるIDを使用するだけでいいと思います。フィードのタイトルや記事が編集されていれば、問題はありません。 – superlogical

答えて

2

ハッシュアプ​​ローチが何らかのサーバ側で追加されたXMLのコメントに、この場合には動作しません。実際のフィードが決して変化しなくても常に頻繁にキャッシュするキャッシング。

このフィードで動作することの1つは、要求した最後の時刻以降に実際に変更された場合にのみ、サーバーにデータを渡すように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ヘッダー(そこにある場合)とフィードのメタデータ(最終更新日、更新期間および更新頻度)を使用して、次回の更新の有無を確認するタイミングを導くことができます。 –

3

なぜフィードのLastUpdatedTimeをチェックするだけではないのですか?これは、新しいものかどうかを伝えるビルトインの方法です。代わりにハッシュの、あなたは単にLastUpdatedTimeを追跡し、最新の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は常にそれでうまくいくのですか?私が索引付けしたいフィードの大部分は、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); 

・ホープ、このことができます:行くための最善の方法は、とにかくフィードをロードし、記事のハッシュだけの内容、あなたがこのような任意の文字列をハッシュすることができますです私見

関連する問題