HtmlAgilityPack come estrarre html tra alcuni tag

c# html-agility-pack

Domanda

Ho bisogno di estrarre tutto il paragrafo da un html e anche tutto il testo tra i tag.

questo codice non funziona quando il testo analizzato in HtmlDocument viene modificato rispetto a quello originale. Nel campione

some <br />text

è cambiato in

some <br>text

es:

string s = "<p>firt paragraph</p>some <br />text<p>another paragraph</p><span>some text between span</span><p>hellow word</p>";
        HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
        doc.LoadHtml(s);
var nodes = doc.DocumentNode.SelectNodes("//p");
int lastPos = -1;
foreach (HtmlAgilityPack.HtmlNode n in nodes)
{
  if (lastPos > -1)
  {
      string textNotInP = Doc.DocumentNode.OuterHtml.Substring(lastPos, n.StreamPosition - lastPos);
                System.Diagnostics.Debug.WriteLine(textNotInP);
 }
 System.Diagnostics.Debug.WriteLine(n.OuterHtml);
 lastPos = n.StreamPosition + n.OuterHtml.Length;
}

il risultato corretto sarebbe:

<p>firt paragraph</p>
some <br>text
<p>second paragraph</p>
<span>some text between span</span>
<p>third paragraph</p>

ma il codice sopra riportato restituisce questo:

<p>firt paragraph</p>
some <br>text<p
<p>second paragraph</p>
pan>some text between span</span><p
<p>third paragraph</p>

il motivo è che steamPosition restituisce la posizione del nodo relativa al testo originale, non quella analizzata in htmlDocument.

C'è un modo per restituire la posizione di un nodo correlato all'Html analizzato?

Risposta accettata

Puoi utilizzare la proprietà OuterHtml di ciascun elemento <p> per ottenere l'HTML desiderato:

string s = "<p>firt paragraph</p>some <br />text<p>another paragraph</p><span>some text between span</span><p>hellow word</p>";
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(s);
var nodes = doc.DocumentNode.SelectNodes("//p");
foreach (var item in nodes)
{
    Console.WriteLine(item.OuterHtml);
}

produzione :

<p>firt paragraph</p>
<p>another paragraph</p>
<p>hellow word</p>

O se intendi ottenere tutto tra i primi <p> e gli ultimi <p> elementi, inclusi, puoi usare il seguente XPath:

var query = "//node()[preceding-sibling::p or self::p][following-sibling::p or self::p]";

La benna XPath tutti i nodi (o elemento o nodo di testo) che ha: precedenti sibling p e seguendo sibling p , o il nodo stesso è un p elemento.

var nodes = doc.DocumentNode.SelectNodes(query);
foreach (var item in nodes)
{
    Console.WriteLine(item.OuterHtml);
}

produzione :

<p>firt paragraph</p>
some
<br />
text
<p>another paragraph</p>
<span>some text between span</span>
<p>hellow word</p>


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é