HTML AgilityPack을 사용하여 브레이크 라인으로 HTML 구문 분석하기

c# html-agility-pack parsing

문제

난 내가 의해 점선의 집합 추출 할 수 있도록 특정 HTML 문자열을 구문 분석하려고 <br/> 브레이크 라인. 입력 HTML은 다음과 같습니다.

<div class="PlainText">
  DATE: 2013-10-28 20:00:43 -0500 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  <br/> //Notice this has two break lines, i would like to stop after seeing two consecutive break lines.
</div>

큰 HTML 문서에서이 div를 사용하여 HTML ChildNodes 를 얻을 수있었습니다.

<div class="PlainText">
  DATE: 2013-10-28 20:00:43 -0500 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  Item 1: Text1 <br/>
  <br/> //Notice this has two break lines, i would like to stop after seeing two consecutive break lines.
</div>

나는 여기에서 어디로 가야하는지 완전히 확신하지 못한다. 나는 2 개의 파선을보고 멈출 때까지 모든 본문을 읽고 싶다.

편집하다

나는 childNodes에의 보았다 nodes 비주얼 스튜디오 런타임 관리자에서 실제로 두 consectuive하지 않다가 발견 <br/> 라인하지만 하나의 브레이크 라인과 #text 의 innerHTML을의 존재의와 태그 \n 새로운 라인 문자.

여기에 이미지 설명을 입력하십시오.

수락 된 답변

이 같은 것이 작동해야합니다.

[Test]
public void Test()
{
    var x = ReadTillTwoBr(GetDivClass()).ToList();
}

public HtmlNode GetDivClass()
{
    var html = @"<html><div class=""PlainText"">
            DATE: 2013-10-28 20:00:43 -0500 <br/>
            Item 1: Text1 <br/>
            Item 1: Text1 <br/>
            Item 1: Text1 <br/>
            Item 1: Text1 <br/>
            <br   /> //Notice this has two break lines, i would like to stop after seeing two consecutive break lines.
            Item 3
        </div></html>";
    var doc = new HtmlDocument();
    doc.LoadHtml(html);

    return doc.DocumentNode
                .Descendants("div").First(x => x.Attributes.Contains("class") &&
                                                x.Attributes["class"].Value.Contains("PlainText"));

}

public IEnumerable<string> ReadTillTwoBr(HtmlNode node)
{
    var nonEmptyNodes =
        node.ChildNodes.Except(node.ChildNodes.Where(f => f.Name == "#text" && String.IsNullOrWhiteSpace(f.InnerHtml)))
            .ToList();

    foreach (var n in nonEmptyNodes)
    {
        if (IsBr(n) && IsBr(n.NextSibling))
        {
            yield break;
        }

        if (n.Name == "#text")
        {
            yield return n.InnerText.Trim();
        }
    }
}

public bool IsBr(HtmlNode n)
{
    return n != null && n.NodeType == HtmlNodeType.Element && n.Name == "br";
}

어느 쪽을 돌려 주는가

여기에 이미지 설명을 입력하십시오.

두 명의 br 후에 주석이 어떻게 반환되지 않았는지 주목하십시오.

편집하다:

나는 빈 제거 #text 마지막 두 사이에 줄 바꿈이있을 때부터 값을 br 태그 당신이 실제로 얻을 #text 줄 바꿈에 태그를. 나는 이것이 개행 혼란이있는 곳이라고 생각한다.


인기 답변

XPath //div[@class='PlainText'] 를 사용하여 필요한 div 노드를 가져올 수 있습니다. div에서 하위 노드를 가져갈 때 다음 형제 노드를 확인할 수도 있습니다.

HtmlDocument doc = new HtmlDocument();
doc.Load("index.html");
Func<HtmlNode, bool> notTwoBrakes = 
    n => (n.Name != "br" || n.NextSibling != null && n.NextSibling.Name != "br");
var nodes = doc.DocumentNode.SelectNodes("//div[@class='PlainText']")
               .Select(div => div.ChildNodes.TakeWhile(notTwoBrakes));

가독성을 위해 인라인 람다를 사용하지 않습니다. 조건은 다음과 같이 작동합니다.

  • 다음 노드가 null인지 검사하고, null 인 경우 현재 노드를 가져옵니다.
  • 다음 노드가 br 노드인지 확인 (그렇지 않은 경우) - 현재 노드 가져 오기
  • 현재 노드가 br 노드인지 확인합니다. 그렇지 않은 경우 - 현재 노드를 가져옵니다.
  • 그렇지 않으면 하위 노드 가져 가기 중지

결과:

여기에 이미지 설명을 입력하십시오.




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