【问题标题】:Better way to add a style attribute to Html using HtmlAgilityPack使用 HtmlAgilityPack 向 Html 添加样式属性的更好方法
【发布时间】:2012-08-17 05:58:52
【问题描述】:

我正在使用 HtmlAgilityPack。我正在搜索所有 P 标签并在 P 标签内的样式中添加“margin-top:0px”。

如您所见,这有点“强制”margin-top 属性。似乎必须有更好的方法来使用 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”的方式处理样式属性。

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

【问题讨论】:

    标签: c# html html-agility-pack


    【解决方案1】:

    您可以使用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);
    }
    

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

    【讨论】:

    • 谢谢亚历克斯,我喜欢这些改变,我会去做。我已经对你投了赞成票,但现在想保留这个问题。我希望有人知道 HtmlAgilityPack 中的某些功能,它将解析样式属性并允许我通过某些集合类型结构添加边距。我看了但找不到,但这并不意味着它不存在。
    • @Gene S,我真的怀疑 AgilityPack 可以解析 style 属性的内容。但是您可以尝试使用 string.Split 方法将属性值拆分为分号 (;) 字符,处理这些值,然后使用 string.Join 打包这些值。
    • 我想过。也许我会创建一些扩展方法,让它看起来融入到 AgilityPack 中。感谢您的反馈。
    • 没有理由不能为样式标签添加 CSS 解析器。 This might do the trick
    【解决方案2】:

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

    另外,AgilityPack 没有这种功能,但 .Net Framework 肯定有。请注意,这仅适用于 .Net 4,如果您使用的是早期版本,情况可能会有所不同。 首先,System.Web.dll 带有CssStyleCollection Class,这个类已经包含了解析内联 css 所需的所有内容,只有一个问题,它的构造函数是内部的,所以解决方案有点“hacky”。 首先,要构造一个类的实例,你只需要一点反射,代码已经完成here。请记住,这现在有效,但可能会在未来版本的 .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 的解决方案,但由您决定。 :)

    【讨论】:

    • 我的直觉告诉我也要采用 Alex 的解决方案,但我感谢您的意见。我很高兴知道我并没有忽略敏捷包中的某些内容。
    猜你喜欢
    • 2016-07-28
    • 2015-12-18
    • 1970-01-01
    • 2019-04-30
    • 1970-01-01
    • 2018-02-19
    • 2016-08-05
    • 1970-01-01
    • 2019-07-15
    相关资源
    最近更新 更多