Jak*_*son 1 c# dom html-agility-pack
我正在使用HTMLAgility Pack对HTML输出进行一些即时修改 - 查找所有文本节点并替换它们:
const string xpath = "//*[not(self::script or self::style)]/text()[normalize-space(.) != '']";
var docNodes = doc.DocumentNode.SelectNodes(xpath).ToList();
foreach (var htmlNode in nodes)
{
var parent = htmlNode.ParentNode;
var newNode = new HtmlNode(HtmlNodeType.Text, doc, 0){InnerHTML = "Test"};
parent.ReplaceChild(newNode, htmlNode);
}
Run Code Online (Sandbox Code Playgroud)
但是,如果textnode不是父节点的唯一子节点,这似乎会导致问题.例如:
<label>Email:<br><input name="txtID" type="text" id="txtID" class="input"></label>
Run Code Online (Sandbox Code Playgroud)
在替换之后,访问doc.DocumentNode.OuterHTML会导致以下异常:无法将类型为"HtmlAgilityPack.HtmlNode"的对象强制转换为"HtmlAgilityPack.HtmlTextNode".
我做错了吗?我无法真正去"清理"可能贯穿此内容的所有原始HTML文档.
看来这是一个问题,HtmlNode(HtmlNodeType, HtmlDocument, int)你使用的构造函数和方法InnerHtml和InnerText方法之间的不一致.HtmlNode构造函数创建一个类型的节点HtmlNode(但将节点的类型设置为传递的值).如果你想获得InnerHtml或InnerText此节点,AgilityPack执行是这样的:
case HtmlNodeType.Text:
html = ((HtmlTextNode)this).Text;
Run Code Online (Sandbox Code Playgroud)
这实际上导致InvalidCastException你提到.
为避免这种情况,我建议使用另一种使用HtmlDocument.CreateTextNode()方法创建文本节点的方法:
foreach (var htmlNode in nodes)
{
var parent = htmlNode.ParentNode;
var newNode = doc.CreateTextNode();
newNode.InnerHtml = "Test";
parent.ReplaceChild(newNode, htmlNode);
}
Run Code Online (Sandbox Code Playgroud)
这将正确替换您的文本节点.
| 归档时间: |
|
| 查看次数: |
802 次 |
| 最近记录: |