我刚写了这个测试,看看我是不是疯了......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
namespace HtmlAgilityPackFormBug
{
class Program
{
static void Main(string[] args)
{
var doc = new HtmlDocument();
doc.LoadHtml(@"
<!DOCTYPE html>
<html>
<head>
<title>Form Test</title>
</head>
<body>
<form>
<input type=""text"" />
<input type=""reset"" />
<input type=""submit"" />
</form>
</body>
</html>
");
var body = doc.DocumentNode.SelectSingleNode("//body");
foreach (var node in body.ChildNodes.Where(n => n.NodeType == HtmlNodeType.Element))
Console.WriteLine(node.XPath);
Console.ReadLine();
}
}
}
它输出:
/html[1]/body[1]/form[1]
/html[1]/body[1]/input[1]
/html[1]/body[1]/input[2]
/html[1]/body[1]/input[3]
但是,如果我将<form>
更改为<xxx>
它会给我:
/html[1]/body[1]/xxx[1]
(正如它应该)。所以...看起来这些输入元素不包含在表单中,而是直接包含在正文中,就好像<form>
只是立即关闭它自己一样。那是怎么回事?这是一个错误吗?
通过源头挖掘,我看到:
ElementsFlags.Add("form", HtmlElementFlag.CanOverlap | HtmlElementFlag.Empty);
它有“空”标志,如META和IMG。为什么??表格绝对不应该是空的。
由于我是最初的HAP作者,我可以解释为什么它被标记为空:)
这是因为在2000年设计HAP时,HTML 3.2才是标准。您可能已经意识到标记可以在HTML中完全重叠。即:所有浏览器都支持<b>bold<i>italic and bold</b>italic</i>
( 粗体斜体和粗体斜体)(尽管它在HTML规范中不是正式的)。 FORM标签也可以完美重叠。
由于HAP设计用于处理任何HTML内容,而不是打破当时可以找到的大多数页面,我们只是决定将重叠标记处理为EMPTY(使用ElementFlags属性),因此:
你唯一不能做的就是使用API,使用树模型,XSL或任何程序化的方法。今天,几乎到处都有XHTML / XML,这听起来很奇怪,但这就是我创建ElementFlags的原因:)