我在使用HTML Agility Pack时遇到了一些麻烦。
当我在不包含特定节点的HTML上使用此方法时,我得到一个空引用异常。它起初工作,但后来停止工作。这只是一个片段,还有大约10个foreach循环选择不同的节点。
我做错了什么?
public string Export(string html)
{
var doc = new HtmlDocument();
doc.LoadHtml(html);
// exception gets thrown on below line
foreach (var repeater in doc.DocumentNode.SelectNodes("//table[@class='mceRepeater']"))
{
if (repeater != null)
{
repeater.Name = "editor:repeater";
repeater.Attributes.RemoveAll();
}
}
var sw = new StringWriter();
doc.Save(sw);
sw.Flush();
return sw.ToString();
}
答案 0 :(得分:25)
AFAIK,DocumentNode.SelectNodes
可以返回null
。
这是默认行为,请参阅codeplex上的讨论主题:Why DocumentNode.SelectNodes returns null
因此,解决方法可能是重写foreach
块:
var repeaters = doc.DocumentNode.SelectNodes("//table[@class='mceRepeater']");
if (repeaters != null)
{
foreach (var repeater in repeaters)
{
if (repeater != null)
{
repeater.Name = "editor:repeater";
repeater.Attributes.RemoveAll();
}
}
}
答案 1 :(得分:5)
此内容已更新,您现在可以通过设置doc.OptionEmptyCollection = true
来阻止SelectNodes返回null,如this github issue中所述。
如果没有与查询匹配的节点,这将使它返回一个空集合而不是null(尽管我不知道为什么这不是默认行为)
答案 2 :(得分:2)
在每个?
示例给出打击之前添加简单的.
:
var titleTag = htdoc?.DocumentNode?.Descendants("title")?.FirstOrDefault()?.InnerText;
答案 3 :(得分:1)
根据Alex的回答,但我解决了这个问题:
public static class HtmlAgilityPackExtensions
{
public static HtmlAgilityPack.HtmlNodeCollection SafeSelectNodes(this HtmlAgilityPack.HtmlNode node, string selector)
{
return (node.SelectNodes(selector) ?? new HtmlAgilityPack.HtmlNodeCollection(node));
}
}
答案 4 :(得分:0)
我已经创建了适用于任何IEnumerable<T>
public static List<TSource> ToListOrEmpty<TSource>(this IEnumerable<TSource> source)
{
return source == null ? new List<TSource>() : source.ToList();
}
用法是:
var opnodes = bodyNode.Descendants("o:p").ToListOrEmpty();
opnodes.ForEach(x => x.Remove());