Html Agility Pack을 사용하여 두 HTML 태그 사이에 내용 가져 오기

.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 이 있습니다. 나는 다른 발생할 때까지 바깥 포함 사업부에서 모두를 선택합니다 h1 하고 사업부를 제외합니다.

  • 각 섹션 이름은 여러 개의 하위 태그가있는 h1 아래의 <a> 태그에 있습니다 (약 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 태그는 섹션 헤드에만 나타나는 것으로 가정하고 있지만이 방법을 사용합니다. 그렇지 않은 경우 찾은 H1 노드에서 다른 필터를 확인하기 위해 하위 노드에서 Where를 추가 할 수 있습니다. 여기에는 섹션 이름이있는 다음 자모가 나타날 때까지 찾은 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;
}

인기 답변

그래서 결과적으로 당신이 정말로 원하는 것은 h1-Tag 주변의 div입니까? 그렇다면이 방법이 효과적입니다.

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

또한 귀하의 HTML에 따라 SelectNodes 와 함께 작동합니다. 이렇게 :

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

아, 그리고 이것을 테스트하는 동안 나를 위해 작동하지 않는 것은 contains 메소드의 점이었습니다. 일단 name 속성으로 변경하면 모든 것이 잘 작동합니다.



Related

아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.