HtmlAgilityPack: ¿Cómo verificar si un elemento es visible?

c# html-agility-pack

Pregunta

Estoy haciendo un análisis de HTML y estoy usando HtmlAgilityPack y estoy tratando de verificar si un elemento de nodo sería visible si el HTML se representó en un navegador.

Por visible, probablemente estoy contento con la verificación de los valores de estilo de display y visibility . (A menos que haya algo adicional de lo que debería preocuparme?).

Entonces, ¿cómo puedo hacer esto? ¿Hay una compilación de manera fácil? ¿Puedo usar algo de magia XPath? (No tengo mucho conocimiento de XPath en este momento).

He pensado en analizar manualmente el valor del estilo, pero preferiría guardarlo como último recurso. ¿O es esta mi única opción?

Solo como referencia, el objeto con el que estoy trabajando es algo como esto:

HtmlAgilityPack.HtmlNode node = GetNode();

Respuesta aceptada

OK, así que he logrado hacer esto, al menos para mis necesidades. Tenga en cuenta que, como se ha dicho en otros comentarios, esto no le permite verificar si un elemento será visible (en la pantalla) para el usuario final.

El enfoque que he tomado comprueba algunas reglas básicas: un elemento es "no visible" si el atributo de estilo del elemento contiene display:none o visibility:hidden , O un elemento ancestro tiene las mismas reglas de estilo.

Con eso en mente, aquí está mi código que hace el trabajo por mí:

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

El punto de entrada para esto es IsNodeVisible y verificará la visibilidad del HtmlNode pasó.



Related

Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow