Потеря знака «меньше» в HtmlAgilityPack loadhtml - PullRequest
8 голосов
/ 24 марта 2011

Я недавно начал экспериментировать с HtmlAgilityPack.Я не знаком со всеми его опциями и думаю, что я делаю что-то не так.

У меня есть строка со следующим содержанием:

string s = "<span style=\"color: #0000FF;\"><</span>";

Вы видите, что в моем промежуткеиметь знак «меньше».Я обрабатываю эту строку следующим кодом:

HtmlDocument htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(s);

Но когда я делаю быстрый и грязный взгляд на диапазон, как этот:

htmlDocument.DocumentNode.ChildNodes[0].InnerHtml

, я вижу, что диапазон пуст.

Какой параметр мне нужно установить, чтобы поддерживать знак «меньше».Я уже пробовал это:

htmlDocument.OptionAutoCloseOnEnd = false;
htmlDocument.OptionCheckSyntax = false;
htmlDocument.OptionFixNestedTags = false;

, но безуспешно.

Я знаю, что это недопустимый HTML.Я использую это для исправления недопустимого HTML и использования HTMLEncode на знаках «меньше»

Пожалуйста, направьте меня в правильном направлении.Заранее спасибо

Ответы [ 5 ]

4 голосов
/ 18 апреля 2011

Пакеты Html Agility обнаруживают это как ошибку и создают для нее экземпляр HtmlParseError.Вы можете прочитать все ошибки, используя ParseErrors класса HtmlDocument.Итак, если вы запустите этот код:

    string s = "<span style=\"color: #0000FF;\"><</span>";
    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(s);
    doc.Save(Console.Out);

    Console.WriteLine();
    Console.WriteLine();

    foreach (HtmlParseError err in doc.ParseErrors)
    {
        Console.WriteLine("Error");
        Console.WriteLine(" code=" + err.Code);
        Console.WriteLine(" reason=" + err.Reason);
        Console.WriteLine(" text=" + err.SourceText);
        Console.WriteLine(" line=" + err.Line);
        Console.WriteLine(" pos=" + err.StreamPosition);
        Console.WriteLine(" col=" + err.LinePosition);
    }

Он отобразит это (сначала исправленный текст, а затем подробности об ошибке):

<span style="color: #0000FF;"></span>

Error
 code=EndTagNotRequired
 reason=End tag </> is not required
 text=<
 line=1
 pos=30
 col=31

Таким образом, вы можете попробовать исправитьэта ошибка, поскольку у вас есть вся необходимая информация (включая строку, столбец и положение потока), но общий процесс исправления (не обнаружения) ошибок в HTML очень сложен.

3 голосов
/ 09 марта 2015

Как уже упоминалось в другом ответе, лучшее решение, которое я нашел, - это предварительный анализ HTML для преобразования потерянных символов < в их значение в кодировке HTML &lt;.

return Regex.Replace(html, "<(?![^<]+>)", "&lt;");
2 голосов
/ 12 апреля 2011

Несмотря на то, что данный html недействителен, HtmlAgilityPack все равно сможет его проанализировать.В интернете не редкость ошибка - забыть закодировать «<», и если HtmlAgilityPack используется в качестве сканера, то он должен ожидать плохой HTML.Я протестировал пример в IE, Chrome и Firefox, и все они показывают дополнительные < в виде текста.

Я написал следующий метод, который можно использовать для предварительной обработки строки html и замены всех «незакрытых» '<' символов с "&lt;":

static string PreProcess(string htmlInput)
{
    // Stores the index of the last unclosed '<' character, or -1 if the last '<' character is closed.
    int lastGt = -1; 

    // This list will be populated with all the unclosed '<' characters.
    List<int> gtPositions = new List<int>();

    // Collect the unclosed '<' characters.
    for (int i = 0; i < htmlInput.Length; i++)
    {
        if (htmlInput[i] == '<')
        {
            if (lastGt != -1)
                gtPositions.Add(lastGt);

            lastGt = i;
        }
        else if (htmlInput[i] == '>')
            lastGt = -1;
    }

    if (lastGt != -1)
        gtPositions.Add(lastGt);

    // If no unclosed '<' characters are found, then just return the input string.
    if (gtPositions.Count == 0)
        return htmlInput;

    // Build the output string, replace all unclosed '<' character by "&lt;".
    StringBuilder htmlOutput = new StringBuilder(htmlInput.Length + 3 * gtPositions.Count);
    int start = 0;

    foreach (int gtPosition in gtPositions)
    {
        htmlOutput.Append(htmlInput.Substring(start, gtPosition - start));
        htmlOutput.Append("&lt;");
        start = gtPosition + 1;
    }

    htmlOutput.Append(htmlInput.Substring(start));
    return htmlOutput.ToString();
}
2 голосов
/ 24 марта 2011

Исправьте разметку, потому что ваша HTML-строка недействительна:

string s = "<span style=\"color: #0000FF;\">&lt;</span>";
0 голосов
/ 24 марта 2011

строка "s" - это плохой HTML.

string s = "<span style=\"color: #0000FF;\">&lt;</span>";

это правда.

...