HtmlAgilityPack – 由于某种原因,<form>是否closures?

我只是写了这个testing,看看我是不是疯了…

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] 

(正如它应该)。 所以…看起来这些input元素包含在表单中,而是直接放在主体中,就好像<form>刚刚closures了一样。 怎么了? 这是一个错误?


从源头上挖掘,我看到:

 ElementsFlags.Add("form", HtmlElementFlag.CanOverlap | HtmlElementFlag.Empty); 

它有“空”的标志,如META和IMG。 为什么?? 表格绝对应该是空的。

这也是在这个工作项目报告。 它包含来自DarthObiwan的build议解决方法。

你可以改变这个,不用重新编译。 ElementFlags列表是HtmlNode类的静态属性。 它可以被删除

  HtmlNode.ElementsFlags.Remove("form"); 

在做文件加载之前

由于我是原始的HAP作者,我可以解释为什么它被标记为空:)

这是因为在2000年deviseHAP时,HTML 3.2是标准。 你可能知道标签可以完全重叠在HTML中。 即:所有浏览器都支持<b>bold<i>italic and bold</b>italic</i>粗体斜体和粗体斜体)(尽pipe它在HTML规范中并不正式)。 FORM标签也可以完美重叠。

由于HAP被devise为处理任何HTML内容,而不是打破当时可以find的大多数页面,所以我们只是决定将重叠标记作为EMPTY(使用ElementFlags属性)处理:

  • 你仍然可以加载它们
  • 你可以保存它们而不破坏原来的HTML(如果你不需要任何编程方式的表单里面的东西)。

唯一不能做的就是和API一起工作,使用树模型,也不用XSL,或者其他程序化的东西。 今天,随着XHTML / XML几乎到处都是,这听起来很奇怪,但这就是为什么我创build了ElementFlags 🙂