HtmlAgilityPack: как интерпретировать текст без тегов в HTML - PullRequest
1 голос
/ 26 июня 2011

Знайте, что заголовок немного расплывчатый, вот пример:

<DIV>
 <DIV>title1</DIV>
 line1<br/>
 line2<br/>
 <DIV>title2</DIV>
 line2.1<br/>
 line2.2<br/>
</DIV>

Как я могу получить line1<br/>line2<br/> для title1 и line2.1<br/>line2.2<br/> для title2?Я использую HtmlAgilityPack и SharpQuery вместе.

Спасибо.

Возможное разрешение

После исследования и пробных попыток мне удалось получить их, используя LinePosition и "// div / text ()"

public static HtmlNodeCollection getNodes(string html, string xpath)
{
    if (html.Length <= 0) { return null; }
    HtmlDocument doc = new HtmlDocument();
    doc.LoadHtml(html);
    return doc.DocumentNode.SelectNodes(xpath);
}

foreach (HtmlNode node in getNodes(html, "//div"){
    foreach (HtmlNode plain_node in getNodes(html, "//div/text()")
    {
        if (plain_node.LinePosition <= node.LinePosition)
        {
            currentHtml += plain_n.InnerHtml + "<br/>";
        }
    }
}

Любой другой способ получше?

Ответы [ 2 ]

2 голосов
/ 27 июня 2011

Редко существует одно уникальное решение проблемы соответствия html.Хотя ваше решение теперь работает нормально и с вашим примером, выражение //div будет рекурсивно искать все элементы div в корневом каталоге.

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

Я бы предложил что-то вроде этого, что более избирательно:

        HtmlDocument doc = new HtmlDocument();
        doc.Load(yourHtmlFile);

        foreach (HtmlNode node in doc.DocumentNode.SelectNodes("/div/div[starts-with(text(), 'title')]/following-sibling::text()[normalize-space(.) != '']"))
        {
            Console.WriteLine(node.InnerText.Trim());
        }

Это означает

  • Поиск div элементов из корня
  • Затем поиск div элементов под
  • Фильтрация (используя [...]) этих элементов и выбор только техс внутренним text, начинающимся с 'title'
  • Затем ищите все следующие родственные элементы типа text
  • Отфильтруйте эти элементы и выберите только те, которые не являются пустыми или только пробелами

Для получения справки по осям XPATH .

см. Эту ссылку.
0 голосов
/ 26 июня 2011

Предполагая, что структура всегда одинакова, вы можете получить div, а затем получить оба их NextSiblings

...