Best way to add style attribute in Html with HtmlAgilityPack

I am using HtmlAgilityPack. I look through all the P tags and add "margin-top: 0px" to the style in the P tag.

As you can see, this is a curious β€œcrude force” of the margin-top attribute. There seems to be a better way to do this with HtmlAgilityPack, but I could not find it, and the HtmlAgilityPack documentation does not exist.

Does anyone know a better way?

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 based on Alex's suggestions. I would like to know if the HtmlAgilityPack has built-in functionality that will handle style attributes more than "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); } } 
+4
source share
2 answers

You can simplify your code a bit with the HtmlNode.GetAttributeValue method and make your "margin-top" magic string constant:

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

Not a very significant improvement, but this code is simpler than for me.

+5
source

First of all, are you sure you need more than you asked for? Alex's solution should just work perfectly for your current problem, if it is always so β€œeasy”, why bother and add more complexity to it?

Anway, AgilityPack does not have this feature, but it certainly has the .Net Framework. Note that this is all for .Net 4, if you are using an earlier version, things could be a little different. The first one, System.Web.dll comes with the CssStyleCollection Class , this class already has everything built-in that you might want to parse the built-in css, there is only one catch, its constructor is internal, so the solution is a bit hacky. Firstly, to build an instance of the class that you need, it is slightly reflected, the code for this is already done here . Just keep in mind that this works now, but may break in a future version of .Net. All that remains is very 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 some reason you cannot add a link to System.Web (it will be if you use .Net 4 Client Profile), there is always the opportunity to use Reflector.

Personally, I would go with Alex's decision, but it's up to you to decide. :)

+3
source

All Articles