我有一个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!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实现这一目标?
答案 0 :(得分:3)
在HTML Agility Pack中似乎没有对内联样式字符串解析的任何支持,但.NET在System.Web.UI
中确实具有一些支持WebForms控件的功能。
它被称为CssStyleCollection
,它会将您的style
字符串转换为一个很好的字符串键/值对数组,并允许您删除不需要的特定键
但是,由于它是WebControl使用的内部工具,因此它没有公共构造函数。相反,你必须通过反射来实例化它,或者使用像这样的黑客;
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
检索新的分隔样式字符串。
重要提示:我还没有对此进行测试,但这个过程看起来很简单,如果有点hacky。我可能还会遇到一些惊喜。特别是,我不知道它如何处理同一个字符串中有多个重复样式设置的情况;
top:0;margin-left:20;top:10;
在内联样式字符串中,浏览器将遵循最后指定的值,因此top:10
获胜。但是,由于CssStyleCollection
使用唯一键,因此无法同时存储top
个值,也很可能会丢弃一个。
答案 1 :(得分:1)
我认为你只需要使用HAP来抓取你要清理的元素,从属性中获取样式然后循环它们以手动清理它们。
我分开&#34;;&#34;那么&#34;:&#34;获取名称/值对。循环遍历它们,将名称小写并将其放入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;
}
无论如何都是这样的。
答案 2 :(得分:0)
使用HTML包和正则表达式。在之前匹配名称:选择文本之后:直到下一个;应该给你一系列的职位?然后从字符串中删除那些位置?希望有道理:)
你可以按照上面的方式进行,但我会变得混乱。如果可能,请使用正则表达式:)
答案 3 :(得分:0)
在HAP中有一种非常简单的编辑样式属性的方法,如以下示例所示: https://html-agility-pack.net/knowledge-base/12062495/better-way-to-add-a-style-attribute-to-html-using-htmlagilitypack。
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);
}
答案 4 :(得分:0)
我的解决方案是删除样式属性中的旧元素,然后可以添加所需的另一个元素。 我有例子:
<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;"> </span>
我要删除font-family:Calibri;。您可以看到style属性中的每个元素都由“;”分隔。因此,您只需找到所需属性的索引和“;”索引之后最接近的。删除它并添加或不添加任何东西。
我的示例代码删除元素font-family:Calibri并添加font-family:Time新罗马字是:
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;
}
那是我的解决方案。享受吧!