HTML Agility Pack Null Référence

J’ai quelques problèmes avec le pack d’agilité HTML.

J’obtiens une exception de référence null lorsque j’utilise cette méthode sur HTML ne contenant pas le nœud spécifique Cela a fonctionné au début, mais ensuite il a cessé de fonctionner. Ce n’est qu’un extrait et il y a environ 10 autres boucles foreach qui sélectionnent différents nœuds.

Qu’est-ce que je fais mal?

public ssortingng Export(ssortingng 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.Atsortingbutes.RemoveAll(); } } var sw = new SsortingngWriter(); doc.Save(sw); sw.Flush(); return sw.ToSsortingng(); } 

Autant que je sache, DocumentNode.SelectNodes peut renvoyer null si aucun nœud n’est trouvé.

Ceci est le comportement par défaut, voir un fil de discussion sur codeplex: Pourquoi DocumentNode.SelectNodes renvoie null

La solution pourrait donc consister à réécrire le bloc 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.Atsortingbutes.RemoveAll(); } } } 

Vous ajoutez simple ? avant chaque . exemple sont donnés coup:

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

Cela a été mis à jour et vous pouvez maintenant empêcher SelectNodes de renvoyer null en définissant doc.OptionEmptyCollection = true , comme indiqué dans ce problème de github .

Cela le fera retourner une collection vide au lieu de null s’il n’y a pas de nœuds qui correspondent à la requête (je ne sais pas pourquoi ce n’était pas le comportement par défaut pour commencer, cependant)

Selon la réponse d’Alex, mais je l’ai résolu comme ceci:

 public static class HtmlAgilityPackExtensions { public static HtmlAgilityPack.HtmlNodeCollection SafeSelectNodes(this HtmlAgilityPack.HtmlNode node, ssortingng selector) { return (node.SelectNodes(selector) ?? new HtmlAgilityPack.HtmlNodeCollection(node)); } } 

J’ai créé une extension universelle qui fonctionnerait avec n’importe quel IEnumerable

 public static List ToListOrEmpty(this IEnumerable source) { return source == null ? new List() : source.ToList(); } 

Et l’utilisation est:

 var opnodes = bodyNode.Descendants("o:p").ToListOrEmpty(); opnodes.ForEach(x => x.Remove());