4

我编写了一段代码,它使用System.ServiceModel.Syndication库来解析 RSS 提要。

问题是,对于我的一个提要(由 facebook 提供),我在响应末尾得到以下行,并且 Syndication 库无法解析提要,因为它说文本是无效的 XML,它说这是因为这个部分:

  ...
  </channel>
  <access:restriction relationship="deny" xmlns:access="http://www.bloglines.com/about/specs/fac-1.0" />
</rss>

我确定这里缺少一些东西,因为提要和解析库都来自大公司(分别是 Facebook 和 Microsoft)。

你们中的任何人都可以帮忙吗?或者一个更好的不依赖于 XML 有效性的解析器?

PS这是我的RSS提要网址:
http ://www.facebook.com/feeds/page.php?id=202296766494181&format=rss20

这是我解析提要响应的方式:

var stringReader = new StringReader(resp);
var xreader = XmlReader.Create(stringReader);
var xfeed = System.ServiceModel.Syndication.SyndicationFeed.Load(xreader);

我得到的例外是:

System.Xml.XmlException: 'Element' is an invalid XmlNodeType. Line 282, position 4.

在 System.Xml.XmlReader.ReadEndElement() ...

4

1 回答 1

8

SyndicationFeed 似乎对 facebook 使用的 access:restriction 元素有问题。请参阅http://social.msdn.microsoft.com/Forums/ar/xmlandnetfx/thread/7045dc1c-1bd9-409a-9568-543e74f4578d上的最新主题

Michael Sun (MSFT) 写道:“刚刚看到 Martin 的帖子!非常有帮助!我还对这个问题进行了一些研究。该元素来自 Bloglines,http://www.bloglines.com/index.html。听起来像是 facebook 的扩展正在使用它的 RSS 2.0 提要,http: //www.feedforall.com/access-namespace.htm。从这篇文章来看,似乎 Rss20FeedFormatter 不是唯一不支持这些元素的。

我同意 Martin 使用 XDocument (LINQ to XML) 来解析 RSS 提要。或者,如果您正在通过 C# 构建一些大型应用程序,Facebook C# SDK 也会很有帮助, http: //facebooksdk.codeplex.com/ "

编辑:

然而,Atomfeed 似乎没有遇到这个问题。所以最简单的解决方案是使用这个链接(http://www.facebook.com/feeds/page.php?id=202296766494181&format=atom10)。因此将格式参数从 rss20 更改为atom10

    HttpWebRequest req = WebRequest.Create(@"http://www.facebook.com/feeds/page.php?id=202296766494181&format=atom10") as HttpWebRequest;
        req.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
        using (Stream responseStream = req.GetResponse().GetResponseStream())
        {
            using (XmlReader xr = XmlReader.Create(responseStream))
            {
                SyndicationFeed feed = SyndicationFeed.Load(xr);
            }
        }

另一种替代方法是编写一个继承的 XMLTextReader 覆盖 ReadEndElement 方法,方法是跳过通道结束标记之后的任何元素。(请注意,下面的代码没有任何保证,因为我认为自己仍然是一个新手 c# 开发人员。请随时纠正任何可能的错误)

public class FaceBookReader : XmlTextReader
{
    public FaceBookReader(Stream stream)
        : base(stream) { }

    public FaceBookReader(String url)
        : base(url) { }

    public override void ReadEndElement()
    {
        string elementTag = this.LocalName.ToLower();

        base.ReadEndElement();

        // When we've read the channel End Tag, we're going to skip all tags
        // until we reach the a new Ending Tag which should be that of rss
        if (elementTag == "channel")
        {
            while (base.IsStartElement())
            {
                base.Skip();
            }
        }
    }
}
于 2011-10-16T19:20:39.750 回答