C# 使用HtmlAgilityPack向Html添加样式属性的更好方法

C# 使用HtmlAgilityPack向Html添加样式属性的更好方法,c#,html,html-agility-pack,C#,Html,Html Agility Pack,我正在使用HtmlAgilityPack。我正在搜索所有的P标签,并在P标签内的样式中添加一个“边距顶部:0px” 正如你所看到的,这是一种“暴力强迫”的边缘顶部属性。似乎必须有更好的方法使用 HtmlAgilityPack,但我找不到它,HtmlAgilityPack文档也不存在 有人知道更好的方法吗 HtmlNodeCollection pTagNodes = node.SelectNodes("//p[not(contains(@style,'margin-top'))]"); if (

我正在使用HtmlAgilityPack。我正在搜索所有的P标签,并在P标签内的样式中添加一个“边距顶部:0px”

正如你所看到的,这是一种“暴力强迫”的边缘顶部属性。似乎必须有更好的方法使用 HtmlAgilityPack,但我找不到它,HtmlAgilityPack文档也不存在

有人知道更好的方法吗

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

更新:我根据Alex的建议修改了代码。还想知道是否有一些内置的 HtmlAgilityPack中的功能将以更“DOM”的方式处理样式属性


通过使用
HtmlNode.GetAttributeValue
方法,并将“margin top”魔术字符串设置为常量,您可以稍微简化代码:

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

这不是一个非常显著的改进,但这段代码对我来说更简单。

首先,你确定你需要比你要求的更多的东西吗?Alex的解决方案应该可以很好地解决您当前的问题,如果它总是那么“简单”,为什么还要费心给它增加更多的复杂性呢

另外,AgilityPack没有这种功能,但是.Net框架肯定有。请注意,这些都是针对.NET4的,如果您使用的是早期版本,则情况可能会有所不同。 首先,System.Web.dll附带了,这个类已经具备了解析内联css所需的所有内置功能,只有一个缺点,它的构造函数是内部的,所以解决方案有点“黑客”。 首先,为了构建类的实例,您所需要的只是一点反射,其代码已经完成。请记住,这种方法现在可以使用,但在未来的.Net版本中可能会出现问题。 剩下的一切都很简单

CssStyleCollection css = CssStyleTools.Create();
css.Value = "border-top:1px dotted #BBB;margin-top: 0px;font-size:12px";
Console.WriteLine(css["margin-top"]); //prints "0px"
如果您由于某种原因无法添加对System.Web的引用(如果您使用的是.Net 4客户端配置文件),则始终可以使用Reflector


就我个人而言,我同意亚历克斯的解决方案,但这取决于你的决定。:)

谢谢Alex,我喜欢这些改变,我会做的。我已经投了你的赞成票,但我想暂时保留这个问题。我希望有人知道HtmlAgilityPack中的一些特性,这些特性将解析样式属性,并允许我通过一些集合类型结构添加边距。我找了一个,但找不到,但这并不意味着它不在那里。@Gene S,我真的怀疑AgilityPack能否解析
style
属性的内容。但是您可以尝试使用
字符串将属性值拆分为分号(
)字符。split
方法,处理这些值,然后使用
字符串打包这些值。Join
。我考虑过这一点。也许我会创建一些扩展方法,让它看起来像是烘焙到AgilityPack中。感谢您的反馈。没有理由不为样式标记添加CSS解析器。我的直觉告诉我也要接受Alex的解决方案,但我感谢你的意见。我很高兴知道我没有忽略敏捷包中的某些东西。
CssStyleCollection css = CssStyleTools.Create();
css.Value = "border-top:1px dotted #BBB;margin-top: 0px;font-size:12px";
Console.WriteLine(css["margin-top"]); //prints "0px"