HtmlAgilityPack - делает
почему-то закрывай себя?

c# html-agility-pack

Вопрос

Я только что написал этот тест, чтобы убедиться, что я сумасшедший ...

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. Зачем?? Формы, безусловно, не должны быть пустыми.

Принятый ответ

Об этом также сообщается в этом документе . В нем содержится предлагаемое решение от DarthObiwan.

Вы можете изменить это без перекомпиляции. Список ElementFlags является статическим свойством класса HtmlNode. Его можно удалить с помощью

    HtmlNode.ElementsFlags.Remove("form");

перед загрузкой документа


Популярные ответы

Поскольку я являюсь оригинальным автором 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 :)



Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow