Mejor manera de agregar un atributo de estilo a Html usando HtmlAgilityPack

c# html html-agility-pack

Pregunta

Estoy usando el HtmlAgilityPack. Estoy buscando en todas las etiquetas P y agregando un "margen superior: 0px" al estilo dentro de la etiqueta P.

Como puede ver, es un poco "forzado brutal" el atributo de margen superior. Parece que tiene que haber una mejor manera de hacerlo usando HtmlAgilityPack pero no pude encontrarlo, y la documentación de HtmlAgilityPack no existe.

¿Alguien sabe de una manera mejor?

        HtmlNodeCollection pTagNodes = node.SelectNodes("//p[not(contains(@style,'margin-top'))]");
        if (pTagNodes != null && pTagNodes.Any())
        {
            foreach (HtmlNode pTagNode in pTagNodes)
            {
                if (pTagNode.Attributes.Contains("style"))
                {
                    string styles = pTagNode.Attributes["style"].Value;
                    pTagNode.SetAttributeValue("style", styles + "; margin-top: 0px");
                }
                else
                {
                    pTagNode.Attributes.Add("style", "margin-top: 0px");
                }
            }
        }



ACTUALIZACIÓN : He modificado el código basado en las sugerencias de Alex. Aún me gustaría saber si hay alguna funcionalidad incorporada en HtmlAgilityPack que manejará los atributos de estilo de una manera más "DOM".

        const string margin = "; margin-top: 0px";

        HtmlNodeCollection pTagNodes = node.SelectNodes("//p[not(contains(@style,'margin-top'))]");
        if (pTagNodes != null && pTagNodes.Any())
        {
            foreach (var pTagNode in pTagNodes)
            {
                string styles = pTagNode.GetAttributeValue("style", "");
                pTagNode.SetAttributeValue("style", styles + margin);
            }
        }

Respuesta aceptada

Podría simplificar un poco su código usando el método HtmlNode.GetAttributeValue y haciendo que su cadena mágica de "margen superior" sea ​​constante:

const string margin = "margin-top: 0";
foreach (var pTagNode in pTagNodes)
{
    var styles = pTagNode.GetAttributeValue("style", null);
    var separator = (styles == null ? null : "; ");
    pTagNode.SetAttributeValue("style", styles + separator + margin);
}

No es una mejora muy significativa, pero este código es más simple para mí.


Respuesta popular

En primer lugar, ¿está seguro de que necesita más de lo que pidió? La solución de Alex debería funcionar bien para su problema actual, si siempre es así de "simple", ¿por qué molestarse y agregarle más complejidad?

De todos modos, AgilityPack no tiene ese tipo de función, pero seguramente el .Net Framework sí lo tiene. Tenga en cuenta que esto es todo para .Net 4, si está utilizando una versión anterior, las cosas podrían ser un poco diferentes. En primer lugar, System.Web.dll viene con la CssStyleCollection Class , esta clase ya tiene todo lo que necesitas para analizar css en línea, solo hay un retén, su constructor es interno, por lo que la solución es un poco "hacky". En primer lugar, para la construcción, una instancia de la clase, todo lo que necesita es un poco de reflexión, el código para eso ya se ha hecho aquí . Solo tenga en cuenta que esto funciona ahora, pero podría interrumpir una futura versión de .Net. Todo lo que queda es muy fácil.

CssStyleCollection css = CssStyleTools.Create();
css.Value = "border-top:1px dotted #BBB;margin-top: 0px;font-size:12px";
Console.WriteLine(css["margin-top"]); //prints "0px"

Si por alguna razón no puede agregar una referencia a System.Web (sería el caso si está utilizando .Net 4 Client Profile) siempre existe la posibilidad de usar Reflector.

Personalmente, me gustaría ir con la solución de Alex, pero depende de usted decidir. :)



Related

Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué