Тег изображения не закрывается с помощью HTMLAgilityPack - PullRequest
9 голосов
/ 17 апреля 2009

Используя HTMLAgilityPack для записи нового узла изображения, кажется, что он удаляет закрывающий тег изображения, например, должно быть, но когда вы проверяете внешний HTML, имеет.

string strIMG = "<img src='" + imgPath + "' height='" + pubImg.Height + "px' width='" + pubImg.Width + "px' />";

HtmlNode newNode = HtmlNode.Create(strIMG);

Это ломает xhtml.

Ответы [ 4 ]

19 голосов
/ 24 ноября 2009

Указание выводить XML, как предлагает Микки, работает, но если у вас есть другие причины не хотеть XML, попробуйте это:

doc.OptionWriteEmptyNodes = true;
3 голосов
/ 23 августа 2012

Редактировать 1: Вот как исправить документ HTML Agilty Pack, чтобы правильно отображать теги изображений (img):

if (HtmlNode.ElementsFlags.ContainsKey("img"))
{   HtmlNode.ElementsFlags["img"] = HtmlElementFlag.Closed;}
else
{   HtmlNode.ElementsFlags.Add("img", HtmlElementFlag.Closed);}

замените «img» на любой другой тег, чтобы исправить их (ввод, выбор и опция часто появляются). Повторите по мере необходимости. Имейте в виду, что это произойдет, а не из-за ошибки HAP, препятствующей одновременной установке флагов «закрыт» и «пусто». Источник: Майк Бридж

Оригинальный ответ: Просто поработав над решением этой проблемы и не найдя достаточных ответов (правильный тип документа, используя параметры «Выводить как XML», «Проверить синтаксис», «AutoCloseOnEnd» и «Создать пустой узел»), я смог решить эту проблему с помощью грязного хака. Это, безусловно, не решит проблему для всех, но для любого, кто возвращает сгенерированный html / xml в виде строки (например, через веб-сервис), простое решение состоит в использовании поддельных тегов, которые пакет гибкости не знает, чтобы сломать. Как только вы закончите делать все, что вам нужно сделать с вашим документом, вызовите следующий метод один раз для каждого тега, что вызовет головную боль (например, option, input и img). Сразу после этого визуализируйте вашу окончательную строку и выполните простую замену каждого тега с префиксом какой-либо строки (в данном случае «Fix_») и верните вашу строку. На мой взгляд, это лишь незначительно лучше, чем решение регулярных выражений, предложенное в другом вопросе, который я не могу найти в данный момент (что-то вроде)

private void fixHAPUnclosedTags(ref HtmlDocument doc, string tagName, bool hasInnerText = false)
{
    HtmlNode tagReplacement = null;
    foreach(var tag in doc.DocumentNode.SelectNodes("//"+tagName))
    {
        tagReplacement = HtmlTextNode.CreateNode("<fix_"+tagName+"></fix_"+tagName+">");
        foreach(var attr in tag.Attributes)
        {
            tagReplacement.SetAttributeValue(attr.Name, attr.Value);
        }
        if(hasInnerText)//for option tags and other non-empty nodes, the next (text) node will be its inner HTML
        {
            tagReplacement.InnerHtml = tag.InnerHtml + tag.NextSibling.InnerHtml;
            tag.NextSibling.Remove();
        }
        tag.ParentNode.ReplaceChild(tagReplacement, tag);
    }
}

В качестве примечания: если бы я был игроком на ставки, я бы предположил, что приведенный выше ответ MikeBridge непреднамеренно определяет источник этой ошибки в пакете - что-то заставляет закрытые и пустые флаги быть взаимоисключающими

Кроме того, после еще нескольких копаний я, похоже, не единственный, кто выбрал этот подход: Параметр HtmlAgilityPack Drops End Tags

Кроме того, в случаях, когда вам нужны ТОЛЬКО непустые элементы, в этом же вопросе перечислено очень простое исправление, а также обсуждение кодекса HAP здесь : по сути, это устанавливает параметр пустого флага перечисленный в ответе Майка Бриджа выше постоянно везде.

3 голосов
/ 13 октября 2009

Существует возможность включить вывод XML, который устраняет эту проблему.

var htmlDoc = new HtmlDocument();
htmlDoc.OptionOutputAsXml = true;
htmlDoc.LoadHtml(rawHtml);
1 голос
/ 26 июля 2012

Это похоже на ошибку в HtmlAgilityPack. Есть много способов воспроизвести это, например:

Debug.WriteLine(HtmlNode.CreateNode("<img id=\"bla\"></img>").OuterHtml);

Выводит искаженный HTML. Использование предложенных исправлений в других ответах ничего не дает.

HtmlDocument doc = new HtmlDocument();
doc.OptionOutputAsXml = true;
HtmlNode node = doc.CreateElement("x");
node.InnerHtml = "<img id=\"bla\"></img>";
doc.DocumentNode.AppendChild(node);
Debug.WriteLine(doc.DocumentNode.OuterHtml);

Создает искаженный XML / XHTML, как <x><img id="bla"></x>

Я создал проблему в CodePlex для этого.

...