Better way to add a style attribute to Html using HtmlAgilityPack

c# html html-agility-pack

Question

The HTMLAgilityPack is what I'm using. I'm going through each and every P tag and adding "margin-top: 0px" to the style.

As you can see, the margin-top property is being rather "brute forced." Although I could not locate it and there is no HtmlAgilityPack documentation, it appears there must be a better method to do this using HtmlAgilityPack.

Anyone have a better idea?

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: I changed the code in accordance with Alex's recommendations. Would still want to know whether HTML Agility Pack has any built-in features that would handle the style attributes in a more "DOM"-like fashion.

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);
    }
}
1
4
12/5/2018 3:43:48 PM

Accepted Answer

Your code might be made a little bit simpler by addingHtmlNode.GetAttributeValue making your "margin-top" magic string a constant, and using:

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

This code is easier, however it's not a huge improvement.

5
8/22/2012 1:02:16 PM

Popular Answer

First off, are you certain that you need more than what you requested? If your issue is always so "easy," why bother adding extra complexity when Alex's answer should suffice?

Anyhow, the AgilityPack doesn't have such feature, but undoubtedly. has Net Framework. Keep in mind that this is all for.Net 4, so your results may vary if you're using a previous version. The CssStyleCollection Class class is included in System.Web.dll and contains all the features you could possibly need for parsing inline CSS, with the exception that its constructor is internal, making the approach rather "hacky." First off, all you need to create a class instance is a little reflection; the code for that has already been written in here. Just be aware that although this now works, it may not in the future versions of.Net. The only thing left is quite simple.

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

If for any reason you are unable to create a reference to System.Web (which would be the case if you are using.Net 4 Client Profile), you may always utilize Reflector.

Personally, I would choose Alex's option, but it is entirely up to you. :)



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow