C# 使用Html Agility Pack从Html字符串中的样式属性中剥离特定样式

C# 使用Html Agility Pack从Html字符串中的样式属性中剥离特定样式,c#,html-parsing,html-agility-pack,C#,Html Parsing,Html Agility Pack,我有一个Html字符串,它包含各种Html,但包括 <span style="display:block;position:fixed;width:100%;height:2000px;background-color:rgba(0,0,0,0);z-index:9999!important;top:0;left:0;cursor:default;"></span> 这看起来很奇怪,但我只想删除style属性中的特定项(对于所有Html元素)。例如,我想删除 pos

我有一个Html字符串,它包含各种Html,但包括

<span style="display:block;position:fixed;width:100%;height:2000px;background-color:rgba(0,0,0,0);z-index:9999!important;top:0;left:0;cursor:default;"></span>

这看起来很奇怪,但我只想删除style属性中的特定项(对于所有Html元素)。例如,我想删除

position:fixed
z-index:9999!重要的和<代码>顶部:0
左:0

仅举几个例子,但保留所有其他内容。现在的问题是,它不一定是
位置:固定的可以是
位置:绝对或其他什么。正如它可以是
z-index:9998或<代码>前20名

我需要能够通过键删除样式元素,所以
位置:*任意*
顶部:*任意*
等。。。。并以不区分大小写的方式执行此操作。所以它会得到
位置:*任何*
位置:*任何*


有没有一种方法可以使用Html Agility Pack实现这一点?

我认为您只需要使用HAP来获取要清理的元素,从属性中获取样式,然后在它们上循环以手动清理它们

我在“;”上拆分,然后在“:”上拆分,以获得名称/值对。在它们上面循环,将名称小写,并将其放入一个switch语句中,该语句带有下拉列表,以方便使用,并且有一个默认值,将名称/值附加到一个新字符串中。然后将新的样式字符串注入到属性中

 // Psuedo code, not the real deal!!
 // Inspired from http://htmlagilitypack.codeplex.com/wikipage?title=Examples
 HtmlDocument doc = new HtmlDocument(); 

 doc.Load("file.htm");
 foreach(HtmlNode span in doc.DocumentElement.SelectNodes("//span[@style]"))
 {
    HtmlAttribute att = span["style"];
    att.Value = CleanStyles(att.Value);
 }
 doc.Save("file.htm");

 // Elsewhere
 public string CleanStyles( string oldStyles ) {
    string newStyles = "";
    foreach( var entries in oldStyle.Split( ';' ) ) {
       var values = entries.Split(':');
       switch( values[0].ToLower() ) {
          case "position":
          case "z-index":
            // Do nothing, skip this value
            break;
          default:
             newStyles += values.Join(':') + ";";
       }
    }  
    return newStyles;
 }

反正是这样的

使用HTML包和正则表达式。匹配前面的名称:选择后面的文本:直到下一步;这应该给你一系列的位置?然后从字符串中删除这些位置?希望这是有道理的:)


你可以按上面的方法做,但我会弄得一团糟。如果可能,请使用正则表达式:)

HTML Agility Pack中似乎不支持内联样式的字符串解析,但是.NET在
System.Web.UI
中确实有一些支持WebForms控件的功能

它被称为
cssstylection
,它将把
style
字符串转换成一个漂亮的字符串键/值对数组,并允许您删除不需要的特定键

但是,由于它是用于WebControl的内部工具,因此没有公共构造函数。相反,您必须通过反射来实例化它,或者使用类似的hack

CssStyleCollection style = new Panel().Style;
一旦创建

style.Value = "YOUR STYLE STRING"; 
然后移除你不想要的东西

style.Remove("position");
style.Remove("z-index");
style.Remove("top");
style.Remove("left");
style.Value
中检索新的分隔样式字符串

重要提示:我还没有测试过这个,但是这个过程似乎足够简单,如果有点不成熟的话。可能有一些我还没有遇到的惊喜。特别是,我不知道它如何处理在同一字符串中存在多个重复样式设置的情况

top:0;margin-left:20;top:10; 

在内联样式字符串中,浏览器将尊重最后指定的值,因此
top:10
获胜。但是,由于
cssstylection
使用唯一键,因此它不能同时存储
top
值,而且很可能会丢弃一个值。

在HAP中有一种非常简单的编辑样式属性的方法,如以下示例所示:


我的解决方案是删除样式属性中的旧元素,您可以添加另一个您想要或不想要的元素。 我举了一个例子:

<span style="font-size:12pt;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:Arial;lang:EN-US;mso-fareast-language:EN-US;mso-ansi-language:AR-SA;">&nbsp;</span>

这就是我的解决方案。享受吧

一些要求:*样式是否总是相同的,或者它们是否有任何样式?*它总是在标签上吗?不,样式可以是任何东西,但不总是跨度标签。但是标签不是问题所在,它能够通过不区分大小写的键从样式属性中删除某些元素。谢谢:)我稍后会尝试一下,看看这是否如预期的那样有效。我喜欢这个。很好地利用了现有的框架,尤其是当你只需要完成它或者一次性开发代码的时候;TOP:0,它可以按预期工作,但它不能处理类似于
背景图像:url('/image.png');背景:url('/image2.png')其中第一条规则应被第二条规则覆盖
<span style="font-size:12pt;font-family:Calibri;mso-fareast-font-family:宋体;mso-bidi-font-family:Arial;lang:EN-US;mso-fareast-language:EN-US;mso-ansi-language:AR-SA;">&nbsp;</span>
foreach (HtmlAgilityPack.HtmlNode span in doc.DocumentNode.SelectNodes("//span[@style]"))
{
    HtmlAgilityPack.HtmlAttribute att = span.Attributes["style"];
    att.Value = ChageFontFamily(att.Value);        
}

private string ChageFontFamily(string value)
{
    //Get index of element you want to remove.
    //Get index of ";" neareast to remove.
    var idxStart = value.IndexOf("font-family:");
    var idxEnd = value.IndexOf(";", idxStart);

    //remove it
    value = value.Remove(idxStart, idxEnd - idxStart + 1);

    //you can add other element like this and return it
    value += "font-family:Time New Roman;";
    return value;
}