使用 Html Agility Pack 从 Html 字符串中的 Style 属性中去除特定样式

lee*_*n3o 4 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>
Run Code Online (Sandbox Code Playgroud)

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

position:fixedz-index:9999!important;top:0;left:0;

仅举几例,但保留其他所有内容。现在的问题是,它不一定position:fixed;是可能的position:absolute;。就像它可能z-index:9998;top:20;等等......

我需要能够通过其键删除风格元素,所以position:*anything*top:*anything*等....并在不区分大小写的方式做到这一点。所以它会得到POSITION:*anything*PoSition:*anything*

有没有办法使用 Html Agility Pack 来实现这一点?

Mem*_*can 5

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

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

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

CssStyleCollection style = new Panel().Style;
Run Code Online (Sandbox Code Playgroud)

一旦创建,

style.Value = "YOUR STYLE STRING"; 
Run Code Online (Sandbox Code Playgroud)

然后删除你不想要的项目;

style.Remove("position");
style.Remove("z-index");
style.Remove("top");
style.Remove("left");
Run Code Online (Sandbox Code Playgroud)

从 中检索新的分隔样式字符串style.Value

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

top:0;margin-left:20;top:10; 
Run Code Online (Sandbox Code Playgroud)

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


Pet*_*son 1

我认为您只需要使用 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;
 }
Run Code Online (Sandbox Code Playgroud)

无论如何,类似的事情。