HtmlAgilityPack - Закрывает ли <form> по какой-то причине?
Я только что написал этот тест, чтобы убедиться, что я сумасшедший...
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. Зачем?? Формы, безусловно, не должны быть пустыми.
Ответы
Ответ 1
Об этом также сообщается в этот workmem. В нем содержится предлагаемое решение от DarthObiwan.
Вы можете изменить это без перекомпиляции. Список ElementFlags - это static в классе HtmlNode. Его можно удалить с помощью
HtmlNode.ElementsFlags.Remove("form");
перед загрузкой документа
Ответ 2
Поскольку я являюсь оригинальным автором HAP, я могу объяснить, почему он обозначен как пустой:)
Это потому, что, когда HAP был разработан, еще в 2000 году, стандарт HTML 3.2 был стандартным. Вероятно, вы знаете, что теги могут полностью перекрываться в HTML. То есть: <b>bold<i>italic and bold</b>italic</i>
( жирный курсив и полужирный курсив) поддерживается всеми браузерами (хотя он официально не указан в спецификации HTML). И тег FORM также может отлично перекрываться.
Поскольку HAP был разработан для обработки любого содержимого HTML, а не разбивал большинство страниц, которые вы могли найти в то время, мы просто решили обрабатывать перекрывающиеся теги как EMPTY (используя свойство ElementFlags), поэтому:
- вы можете загрузить их
- вы можете сохранить их обратно, не нарушая оригинальный HTML (если вам не нужно, что внутри формы каким-либо программным способом).
Единственное, что вы не можете сделать, это работать с ними с помощью API, используя древовидную модель, ни с XSL, ни с программным обеспечением.
Сегодня, когда XHTML/XML почти везде, это звучит странно, но поэтому я создал ElementFlags:)