2011-04-27 177 views
6

我在HTML敏捷包中遇到了一些麻煩。HTML敏捷包空參考

當我在不包含特定節點的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

在哪裏異常拋出? – 2011-04-27 09:23:44

+0

對不起,忘了提。它被拋在這一行上:「foreach(doc.DocumentNode.SelectNodes(」// table [@ class ='mceRepeater']「))中的var repeater)」 – tohereknowswhen 2011-04-27 10:07:18

回答

21

據我所知,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

這是有效的。感謝一堆! – tohereknowswhen 2011-04-27 10:45:16

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)); 
    } 
} 
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()); 
+2

我喜歡這個解決方案背後的想法,但使用Enumerable.Empty而不是ToList。這樣你就不會迭代轉換成List。 – brianfeucht 2016-03-21 23:16:07

1

你每天.例如之前添加簡單?給出的打擊:

var titleTag = htdoc?.DocumentNode?.Descendants("title")?.FirstOrDefault()?.InnerText; 
+1

他爲什麼要這樣做? – 2018-01-07 16:29:47

0

這已經更新了,你現在可以防止的SelectNodes從返回通過設置doc.OptionEmptyCollection = true爲空,詳見this github issue

這將使它返回一個空的集合,而不是空,如果有匹配查詢其沒有節點(我不知道這是爲什麼不開始與默認行爲,雖然)