【发布时间】:2011-03-04 03:00:54
【问题描述】:
我正在开发一个 RSS 提要阅读器。某些提要中包含无效标签,例如 和 (对 RSS 无效)。解析它们时出现异常。
为了演示错误,我发布了示例代码。这是一些信息:
异常消息: 意外的节点类型元素。 ReadElementString 方法只能在内容简单或为空的元素上调用。
异常: System.Xml.XmlException。
原始 XML 请参阅此 rss 的 XML:http://www.npr.org/rss/rss.php?id=1001。 请参阅页面来源。问题出在第 56 行(rss 中的 标记)
Exception cmets: 如果您查看原始 RSS,其中有一个 标记。 rss 解析器不喜欢这样,所以它会抛出异常。错误在第 34 行 (Console.WriteLine(ex.Message);)
处理 Rss 提要中的 HTML 标记或忽略它们有什么好处吗?
注意:我添加了微软的代码来扩展 XmlTextReader 类。这是一种绕过 rss 中无效日期的方法。忽略那个。我将它添加到代码中以修复来自 Microsoft 的一个不相关的错误。
这是一个示例代码,您可以运行它来查看异常:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Syndication;
using System.Xml;
using System.Globalization;
using System.IO;
namespace RssTest
{
class Program
{
static void Main(string[] args)
{
DoRSS();
}
public static void DoRSS()
{
string url = "https://west.thomson.com/about/feeds/west_prfeed.xml";
var r = new MyXmlReader(url);
SyndicationFeed feed = SyndicationFeed.Load(r);
Rss20FeedFormatter rssFormatter = feed.GetRss20Formatter();
XmlTextWriter rssWriter = new XmlTextWriter("rss.xml", Encoding.UTF8);
rssWriter.Formatting = Formatting.Indented;
rssFormatter.WriteTo(rssWriter);
rssWriter.Close();
foreach (var i in feed.Items)
{
Console.WriteLine(i.Summary.Text);
}
}
}
//from microsoft
public class MyXmlReader : XmlTextReader
{
private bool readingDate = false;
const string CustomUtcDateTimeFormat = "ddd MMM dd HH:mm:ss Z yyyy"; // Wed Oct 07 08:00:07 GMT 2009
public MyXmlReader(Stream s) : base(s) { }
public MyXmlReader(string inputUri) : base(inputUri) { }
public override void ReadStartElement()
{
if (string.Equals(base.NamespaceURI, string.Empty, StringComparison.InvariantCultureIgnoreCase) &&
(string.Equals(base.LocalName, "lastBuildDate", StringComparison.InvariantCultureIgnoreCase) ||
string.Equals(base.LocalName, "pubDate", StringComparison.InvariantCultureIgnoreCase)))
{
readingDate = true;
}
base.ReadStartElement();
}
public override void ReadEndElement()
{
if (readingDate)
{
readingDate = false;
}
base.ReadEndElement();
}
public override string ReadString()
{
if (readingDate)
{
string dateString = base.ReadString();
DateTime dt;
if (!DateTime.TryParse(dateString, out dt))
dt = DateTime.ParseExact(dateString, CustomUtcDateTimeFormat, CultureInfo.InvariantCulture);
return dt.ToUniversalTime().ToString("R", CultureInfo.InvariantCulture);
}
else
{
return base.ReadString();
}
}
}
}
块引用
【问题讨论】:
-
用 xslt/通过其他方式过滤它,不是吗?
-
@Alex,请再解释一下。当有无效标签时,我得到一个 XML 异常,那么我该如何使用 xslt?
-
您可以尝试在 HtmlAgilityPack 中打开提要 XML,通常在“修复”未闭合标签方面做得很好,使用固定输出 - 不会将此作为解决方案,但值得一试,即使不太可能成功
-
是 XML 解析异常,还是 RSS 阅读器抛出 feed 结构无效的异常?如果您能够将提要作为 XML 源加载,那么您可以将 XML 转换为 RSS 阅读器可以接受的内容。如果它不是格式良好的 XML,那么您需要让提供商修复他们的提要,或者尝试使用“修复”问题并帮助生成格式良好的 XML 的工具清理提要。
-
你能发布一个这个无效 XML 的例子吗?另外,发布无效标签时遇到的异常。