HtmlAgilityPack: come verificare se un elemento è visibile?

c# html-agility-pack

Domanda

Sto facendo un po 'di analisi HTML e sto usando HtmlAgilityPack e sto cercando di verificare se un elemento nodo sarebbe visibile se l'html è stato reso in un browser.

Per visibilità, probabilmente mi accontento di controllare i valori di display e visibility stile. (a meno che non ci sia qualcosa di aggiuntivo di cui dovrei preoccuparmi?).

Quindi, come posso fare questo? C'è una build in modo semplice? Posso usare qualche magia XPath? (Non ho troppa conoscenza di XPath al momento).

Ho pensato di analizzare manualmente il valore dello stile, ma preferirei salvarlo come ultima risorsa. O è questa la mia unica opzione?

Solo per riferimento, l'oggetto con cui lavoro è qualcosa del genere:

HtmlAgilityPack.HtmlNode node = GetNode();

Risposta accettata

OK, quindi sono riuscito a farlo, almeno per i miei bisogni. Si prega di essere avvisati tuttavia, come altri commenti hanno parlato, questo non ti permette di controllare se un elemento sarà visibile (sullo schermo) per l'utente finale.

L'approccio che ho preso semplice controlla alcune regole di base: Un elemento è "non visibile" se l'attributo di stile per l'elemento contiene display:none o visibility:hidden , OPPURE un elemento antenato ha le stesse regole di stile.

Con questo in mente, ecco il mio codice che fa il lavoro per me:

private static bool IsNodeVisible(HtmlAgilityPack.HtmlNode node)
{
    var attribute = node.Attributes["style"];

    bool thisVisible = false;

    if (attribute == null || CheckStyleVisibility(attribute.Value))
        thisVisible = true;

    if (thisVisible && node.ParentNode != null)
        return IsNodeVisible(node.ParentNode);

    return thisVisible;
}

private static bool CheckStyleVisibility(string style)
{
    if (string.IsNullOrWhiteSpace(style))
        return true;

    var keys = ParseHtmlStyleString(style);

    if (keys.Keys.Contains("display"))
    {
        string display = keys["display"];
        if (display != null && display == "none")
            return false;
    }

    if (keys.Keys.Contains("visibility"))
    {
        string visibility = keys["visibility"];
        if (visibility != null && visibility == "hidden")
            return false;
    }

    return true;
}

public static Dictionary<string, string> ParseHtmlStyleString(string style)
{
    Dictionary<string, string> result = new Dictionary<string, string>();

    style = style.Replace(" ", "").ToLowerInvariant();

    string[] settings = style.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

    foreach (string s in settings)
    {
        if (!s.Contains(':'))
            continue;
        string[] data = s.Split(':');
        result.Add(data[0], data[1]);
    }

    return result;
}

Il punto di ingresso per questo è IsNodeVisible e controllerà la visibilità del HtmlNode passato ad esso.




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é