Получение содержимого между двумя тегами HTML с помощью Html Agility Pack

.net c# html-agility-pack

Вопрос

У нас есть абсолютно массивный справочный документ, созданный в Word, и это было использовано для создания еще более массивного и нежесткого документа HTM. Используя C # и эту библиотеку, я хочу только захватить и отобразить один раздел этого файла в любой момент моего приложения. Разделы разделяются следующим образом:

<!--logical section starts here -->
<div>
<h1><span style='mso-spacerun:yes'></span><a name="_Toc325456104">Section A</a></h1>
</div>
 <div> Lots of unnecessary markup for simple formatting... </div>
 .....
<!--logical section ends here -->

<div>
<h1><span style='mso-spacerun:yes'></span><a name="_Toc325456104">Section B</a></h1>
</div>

Логически говоря, a теге есть H1 с именем раздела. Я хочу выбрать все из внешнего, содержащего div, пока не столкнутся с другим h1 и не исключу этот div.

  • Каждое имя раздела расположено в теге <a> под h1 который имеет несколько дочерних элементов (около 6)
  • Логический раздел отмечен комментариями
  • Эти комментарии не существуют в фактическом документе

Моя попытка:

var startNode = helpDocument.DocumentNode.SelectSingleNode("//h1/a[contains(., '"+sectionName+"')]");
//go up one level from the a node to the h1 element
startNode=startNode.ParentNode;

//get the start index as the index of the div containing the h1 element
int startNodeIndex = startNode.ParentNode.ChildNodes.IndexOf(startNode);

//here I am not sure how to get the endNode location. 
var endNode =?;

int endNodeIndex = endNode.ParentNode.ChildNodes.IndexOf(endNode);

//select everything from the start index to the end index
var nodes = startNode.ParentNode.ChildNodes.Where((n, index) => index >= startNodeIndex && index <= endNodeIndex).Select(n => n);

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

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

Я думаю, что это будет сделано, хотя предполагается, что теги H1 появляются только в главах разделов. Если это не так, вы можете добавить Where на потомках, чтобы проверить наличие других фильтров на любых найденных им узлах H1. Обратите внимание, что это будет включать всех братьев и сестер div, которые он находит, до тех пор, пока они не дойдут до следующего с именем раздела.

private List<HtmlNode> GetSection(HtmlDocument helpDocument, string SectionName)
{
    HtmlNode startNode = helpDocument.DocumentNode.Descendants("div").Where(d => d.InnerText.Equals(SectionName, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
    if (startNode == null)
        return null; // section not found

    List<HtmlNode> section = new List<HtmlNode>();
    HtmlNode sibling = startNode.NextSibling;
    while (sibling != null && sibling.Descendants("h1").Count() <= 0)
    {
        section.Add(sibling);
        sibling = sibling.NextSibling;
    }

    return section;
}

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

Итак, что вы действительно хотите в результате, это div вокруг h1-Tag? Если да, то это должно сработать.

helpDocument.DocumentNode.SelectSingleNode("//h1/a[contains(@name, '"+sectionName+"')]/ancestor::div");

Также работает с SelectNodes зависимости от вашего Html. Как это:

helpDocument.DocumentNode.SelectNodes("//h1/a[starts-with(@name,'_Toc')]/ancestor::div");

О, и, проверяя это, я заметил, что вещь, которая не работает для меня, была точкой в ​​методе contains, как только я изменяю ее на атрибут name, все работает нормально.



Related

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