C#计算xml提要的哈希的最佳方法是什么

时间:2011-10-24 18:37:44

标签: c# xmlreader

我想检测一个Feed是否发生了变化,我能想到的唯一方法就是散列xml文档的内容并将其与feed的最后一个哈希值进行比较。

我正在使用XmlReader,因为SyndicationFeed使用它,所以理想情况下我不想加载联合供稿,除非供稿已更新。

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

3 个答案:

答案 0 :(得分:3)

为什么不检查Feed的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...
        }
    }
}

答案 1 :(得分: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));

当然,通过这种方式,你会发现内容的任何变化,即使是最轻微的。

恕我直言最好的方法是加载Feed无论如何只是散列文章的内容,你可以散列这样的字符串:

var toHash = "string to hash";

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

希望这有帮助。

答案 2 :(得分:2)

哈希方法在这种情况下不起作用,因为某些服务器端缓存添加了XML注释,即使实际的Feed从未发生变化,也经常非常频繁。

对于此Feed,您可以执行的一项操作是使用HTTP条件请求,要求服务器仅在您自上次请求后实际修改数据时才为您提供数据。

例如:

您有一个全局/成员变量来保存Feed中的最后修改日期时间

    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
      }