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());