Gettig Htmlelement basato su HtmlAgilityPack.HtmlNode

c# html html-agility-pack webbrowser-control

Domanda

Io uso HtmlAgilityPack per analizzare il documento html di un controllo webbrowser. Sono in grado di trovare il mio HtmlNode desiderato, ma dopo aver ottenuto il HtmlNode, voglio riaccordare il corrispondente HtmlElement nel WebbrowserControl.Document.

Infatti HtmlAgilityPack analizza una copia offline del documento live, mentre voglio accedere agli elementi live del controllo webbrowser per accedere ad alcuni attributi resi come currentStyle o runtimeStyle

HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(webBrowser1.Document.Body.InnerHtml);
var some_nodes = doc.DocumentNode.SelectNodes("//p"); 
// this selection could be more sophisticated 
// and the answer shouldn't relay on it.
foreach (HtmlNode node in some_nodes)
{
   HtmlElement live_element = CorrespondingElementFromWebBrowserControl(node);
   // CorrespondingElementFromWebBrowserControl is what I am searching for
}

Se l'elemento avesse un attributo specifico potrebbe essere facile ma voglio una soluzione che funzioni su qualsiasi elemento.

Per favore aiutami cosa posso fare al riguardo.

Risposta accettata

l'attributo XPath di HtmlAgilityPack.HtmlNode mostra i nodi sul percorso dalla radice al nodo. Ad esempio \div[1]\div[2]\table[0] . È possibile attraversare questo percorso nel documento live per trovare l'elemento live corrispondente. Tuttavia, questo percorso potrebbe non essere preciso poiché HtmlAgilityPack rimuove alcuni tag come <form> quindi prima di utilizzare questa soluzione aggiungere nuovamente i tag omessi

HtmlNode.ElementsFlags.Remove("form");

struct DocNode  
{
    public string Name;
    public int Pos;
}
///// structure to hold the name and position of each node in the path

Il seguente metodo trova l'elemento live secondo XPath

HtmlNode.ElementsFlags.Remove("form");

struct DocNode  
{
    public string Name;
    public int Pos;
}
///// structure to hold the name and position of each node in the path

il codice per il metodo GetChild usato sopra

HtmlNode.ElementsFlags.Remove("form");

struct DocNode  
{
    public string Name;
    public int Pos;
}
///// structure to hold the name and position of each node in the path

Risposta popolare

HtmlAgilityPack non è in grado di fornire direttamente l'accesso ai nodi direttamente in HTML. Dal momento che hai detto che non c'è uno stile / classe / ID distinto sull'elemento devi attraversare manualmente i nodi e trovare le corrispondenze.

Supponendo che HTML sia ragionevolmente valido (quindi sia il browser che HtmlAgilityPack eseguono la normalizzazione in modo simile) è possibile percorrere coppie di elementi a partire dalla radice di entrambi gli alberi e selezionando lo stesso nodo figlio.

Fondamentalmente puoi creare XPath "basato sulla posizione" sul nodo in un albero e selezionarlo in un altro albero. Xpath avrebbe un aspetto simile (a seconda che tu voglia prestare attenzione solo alle posizioni o alla posizione e al nome del nodo):

 "/*[1]/*[4]/*[2]/*[7]"
 "/body/div[2]/span[1]/p[3]"

passi:

  1. HtmlNode di HtmlNode hai trovato tutti i nodi principali fino alla radice.
  2. Ottenere la radice dell'elemento HTML nel browser
  3. per ogni livello di bambini trova la posizione del figlio corrispondente nella raccolta HtmlNodes nel passaggio 1 nel relativo genitore e trova HtmlElement live tra i figli del nodo attivo corrente.
  4. Passa al bambino appena trovato e torna indietro fino al nodo trovato che stai cercando.



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é