Meilleure façon d'ajouter un attribut de style à HTML à l'aide de HtmlAgilityPack

c# html html-agility-pack

Question

J'utilise le HtmlAgilityPack. Je cherche à travers tous les tags P et ajoute un "margin-top: 0px" au style dans le tag P.

Comme vous pouvez le constater, il s’agit un peu du "forçage brutal" de l’attribut margin-top. Il semble qu'il y ait un meilleur moyen de faire cela en utilisant HtmlAgilityPack mais je ne pouvais pas le trouver et la documentation HtmlAgilityPack est inexistante.

Quelqu'un sait un meilleur moyen?

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



UPDATE : J'ai modifié le code en fonction des suggestions d'Alex. J'aimerais toujours savoir s'il existe une fonctionnalité intégrée dans HtmlAgilityPack qui gérera les attributs de style d'une manière plus "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);
            }
        }

Réponse acceptée

Vous pouvez simplifier un peu votre code en utilisant la méthode HtmlNode.GetAttributeValue et en rendant votre chaîne magique "margin-top" 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);
}

Pas une amélioration très significative, mais ce code est plus simple pour moi.


Réponse populaire

Tout d’abord, êtes-vous sûr d’avoir besoin de plus que ce que vous avez demandé? La solution d'Alex devrait bien fonctionner pour votre problème actuel, si c'est toujours aussi "simple", pourquoi se donner la peine d'ajouter à la complexité?

Quoi qu’il en soit, AgilityPack n’a pas ce type de fonction, mais bien le .Net Framework. Notez que ceci est tout pour .Net 4, si vous utilisez une version antérieure, les choses pourraient être un peu différentes. Premièrement, System.Web.dll est fourni avec la CssStyleCollection Class . Cette classe a déjà tout ce que vous pourriez vouloir pour analyser des CSS en ligne, il n’ya qu’un problème: son constructeur est interne, donc la solution est un peu "bidouilleuse". Tout d’abord, pour construire une instance de la classe, vous avez besoin d’un peu de réflexion, le code correspondant à cela a déjà été fait ici . Gardez simplement à l’esprit que cela fonctionne maintenant, mais pourrait faire l’objet d’une future version de .Net. Tout ce qui reste est vraiment facile

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 vous ne pouvez pas pour une raison quelconque ajouter une référence à System.Web (ce serait le cas si vous utilisez .Net 4 Client Profile), il est toujours possible d'utiliser Reflector.

Personnellement, j'irais avec la solution d'Alex, mais c'est à vous de décider. :)



Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow