HtmlAgilityPack Selezionare EspressioneNodi per ignorare un elemento con un determinato attributo

c# html-agility-pack selectnodes xpath

Domanda

Sto provando a selezionare i nodi eccetto i nodi di script e un ul che ha una classe chiamata 'relativeNav'. Qualcuno può dirmi per favore sulla strada giusta? Ho cercato questo per una settimana e non riesco a trovarlo da nessuna parte. Attualmente ho questo ma ovviamente selezionando anche // ul [@ class = 'relativeNav']. Esiste comunque la possibilità di inserire un'espressione NOT in modo che SelectNode lo ignori?

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

Risposta accettata

Dato un documento Html con una struttura simile a:

<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>

La seguente espressione XPath selezionerà tutti i nodi che non sono elementi di script esclusi tutti i figli di elementi UL con 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>

Aggiornamento: ho dimenticato di dire che se hai bisogno di escludere qualsiasi figlio di ul [class = 'relativeNav'] indipendentemente dalla loro profondità, dovresti usare:

<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>

Se si desidera escludere anche l'elemento ul (un po 'irrilevante nell'esempio precedente poiché l'elemento non contiene testo) è necessario specificare:

<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>

Risposta popolare

Spero che questo sia ciò di cui hai bisogno:

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";
}



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché