Expression HtmlAgilityPack SelectNodes pour ignorer un élément avec un certain attribut

c# html-agility-pack selectnodes xpath

Question

J'essaie de sélectionner des noeuds excepté des noeuds de script et un ul qui a une classe appelée 'relativeNav'. Quelqu'un peut-il me diriger s'il vous plaît sur le bon chemin? Je le recherche depuis une semaine et je ne le trouve nulle part. Actuellement, j'ai ceci mais cela sélectionne évidemment le // ul [@ class = 'relativeNav'] également. Est-il possible de mettre une expression NOT pour que SelectNode l'ignore?

        foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//body//*[not(self::script)]/text()"))
        {
            Console.WriteLine("Node: " + node);
            singleString += node.InnerText.Trim() + "\n";
        }

Réponse acceptée

Étant donné un document HTML avec une structure similaire à:

<html>
<head><title>HtmlDocument</title>
</head>
<body>
<div>
<span>Hello Span World</span>
<script>
Script Text
</script>
</div>
<ul class='relativeNav'>
<li>Hello </li>
<li>Li</li>
<li>World</li>
</ul>
</body>
</html>

L'expression XPath suivante sélectionnera tous les nœuds qui ne sont pas des éléments de script, à l'exclusion de tous les enfants des éléments UL avec la classe 'relativeNav':

<html>
<head><title>HtmlDocument</title>
</head>
<body>
<div>
<span>Hello Span World</span>
<script>
Script Text
</script>
</div>
<ul class='relativeNav'>
<li>Hello </li>
<li>Li</li>
<li>World</li>
</ul>
</body>
</html>

Mise à jour: j'ai oublié de mentionner que si vous devez exclure des enfants de ul [class = 'relativeNav'] quelle que soit leur profondeur, vous devez utiliser:

<html>
<head><title>HtmlDocument</title>
</head>
<body>
<div>
<span>Hello Span World</span>
<script>
Script Text
</script>
</div>
<ul class='relativeNav'>
<li>Hello </li>
<li>Li</li>
<li>World</li>
</ul>
</body>
</html>

Si vous souhaitez également exclure l'élément ul (quelque peu sans importance dans l'exemple ci-dessus car l'élément ne contient pas de texte), vous devez spécifier:

<html>
<head><title>HtmlDocument</title>
</head>
<body>
<div>
<span>Hello Span World</span>
<script>
Script Text
</script>
</div>
<ul class='relativeNav'>
<li>Hello </li>
<li>Li</li>
<li>World</li>
</ul>
</body>
</html>

Réponse populaire

J'espère que c'est ce dont vous avez besoin:

HtmlDocument doc = new HtmlDocument();
var nodesToExclude1 = doc.DocumentNode.SelectNodes("//ul[@class='relativeNav']");
var nodesToExclude2 = doc.DocumentNode.SelectNodes("//body//script");
var requiredNodes = doc.DocumentNode.SelectNodes("//")
                       .Where(node => !nodesToExclude1.Contains(node) &&
                                      !nodesToExclude2.Contains(node));

foreach (HtmlNode node in requiredNodes)
{
    Console.WriteLine("Node: " + node);
    singleString += node.InnerText.Trim() + "\n";
}



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi