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

C#计算xml提要哈希的最佳方法是什么,c#,xmlreader,C#,Xmlreader,我想检测一个提要是否已更改,我能想到的唯一方法是对xml文档的内容进行散列,并将其与提要的最后一次散列进行比较 我之所以使用XmlReader,是因为SyndicationFeed使用它,所以理想情况下,我不想加载SyndicationFeed,除非该feed已经更新 XmlReader reader = XmlReader.Create("http://www.extremetech.com/feed"); SyndicationFeed feed = SyndicationFeed.Load

我想检测一个提要是否已更改,我能想到的唯一方法是对xml文档的内容进行散列,并将其与提要的最后一次散列进行比较

我之所以使用XmlReader,是因为SyndicationFeed使用它,所以理想情况下,我不想加载SyndicationFeed,除非该feed已经更新

XmlReader reader = XmlReader.Create("http://www.extremetech.com/feed");
SyndicationFeed feed = SyndicationFeed.Load(reader);
为什么不检查一下提要的格式呢?这是一种内在的方式告诉你什么是新的或不是。与散列和存储散列不同,您只需跟踪LastUpdateTime并定期将其与LastUpdateTime进行比较:

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...
        }
    }
}

在这种情况下,哈希方法将无法工作,因为某些服务器端缓存会添加XML注释,即使在实际提要从未更改的情况下,该注释也会频繁添加

对于此提要,您可以做的一件事是使用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
      }

如果您真的想采用散列方式,可以执行以下操作:

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);

希望这能有所帮助。

是的,我考虑过这一点,但考虑到某些提要可能无法更新该值,我不知道这有多可靠。但是我又一次可能完全错了:)Wordpress总是玩得很好吗?我要索引的大多数提要都是基于Wordpress的。LastUpdateTime完全不可靠,因为它取决于服务器的协作。请先尝试DateTime。除非必须,否则不要假设并解决问题。是的,您依赖于符合标准的第三方,但这种情况一直存在。我想不出比LastUpdateTime更有用的元数据了。不合规将导致体罚。;-)@PaulSasik我想我会继续使用SyndicationItem中的ID哈希冲突的后果是什么?也就是说,假设两个文档具有相同的散列。可能发生的最糟糕的事情是什么?我做了更多的测试,如果这是您的确切提要,那么在这个提要中有一些注释会定期更改,即使非注释xml标记从未更改,所以我认为哈希方法在任何时候都不会起作用all@MerickOWA我想我会继续使用SyndicationItem中的ID。。可能更容易:)这样,如果对提要标题或文章进行编辑,就不会有问题了@superlogical我添加了另一种可能性,它不依赖于散列,并且通常应该可以工作,尽管它依赖于服务器。+1用于正确使用HTTP。您还可以在响应中使用EXPIRES标头(如果有)和提要中的元数据(上次更新日期、更新周期和更新频率)来指导您下次检查更新的时间/频率。