HtmlAgilityPack을 사용하여 한 번에 한 수준 씩 문서 트리를 탐색합니다. 그러나 node.Descendants(0)
을 호출하면 전체 노드 트리가 반환되는 것으로 보입니다.
참고 : 내 축 어적 HTML 문자열을 붙여 넣으려고했으나 SE 파서가 그것을 좋아하지 않으므로이를 스 니펫으로 추가했습니다.
<html>
<head>
<meta name="generator"
content="HTML Tidy for HTML5 (experimental) for Windows https://github.com/w3c/tidy-html5/tree/c63cc39" />
<title></title>
</head>
<body>
<p id="p1" class="newline">
<span id="span1" class="bold">
<span id="span2" class="literal">BOLD TEXT</span>
</span>
</p>
</body>
</html>
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
var lines = doc.DocumentNode.Descendants().Where(x => x.HasClass("newline")).ToArray();
Console.WriteLine(string.Join("\r\n", lines[0].Descendants(0)
.Select(x => $"{x.Name} {x.Id} {(x as HtmlTextNode)?.Text}")));
위의 코드는 첫 번째 p
태그의 자손을 가져옵니다. 인수로 0
또는 1
을 전달하면 전체 노드 트리를 반환하고 아래에 출력합니다. 문제는 BOLD TEXT
포함하는 텍스트 노드가 p
태그에서 3 단계 아래로 중첩 된 것입니다. 위의 코드를 사용하면 텍스트 노드 span1
을 반환하고 다른 텍스트 노드를 반환 할 것으로 기대합니다.
.Descendants
전화에서 내가 뭘 잘못하고 .Descendants
?
#text
span span1
#text
span span2
#text BOLD TEXT
#text
#text
편집 : 일시적인 해결 방법은 부모 노드가 현재 노드와 동일한 하위 노드 만 얻는 것입니다. 그래도 좀 더 실용적인 솔루션을 찾고 있습니다.
Console.WriteLine(string.Join("\r\n", lines[0].Descendants(0)
.Where(x => x.ParentNode == lines[0])
.Select(x => $"{x.Name} {x.Id} {(x as HtmlTextNode)?.Text}")));
나는 같은 문제가있어, 인터넷 검색을 시작하고 귀하의 질문을 발견 :). 그런 다음 개발자에게 직접 물어보기로했습니다 . 그리고 대답은 다음과 같습니다.
코드에 따르면 다른 방식으로 동작합니다.
/// <summary>
/// Gets all Descendant nodes in enumerated list
/// </summary>
/// <returns></returns>
public IEnumerable<HtmlNode> Descendants(int level)
{
if (level > HtmlDocument.MaxDepthLevel)
{
throw new ArgumentException(HtmlNode.DepthLevelExceptionMessage);
}
foreach (HtmlNode node in ChildNodes)
{
yield return node;
foreach (HtmlNode descendant in node.Descendants(level + 1))
{
yield return descendant;
}
}
}
모든 자손을 사용하고 더 이상 자손이 없거나 최대 레벨에 도달 할 때까지 레벨을 1 씩 증가시켜 하위를 가져옵니다 (int.MaxValue). 그러나 나는 당신과 동의한다, 아마 지정된 수준에 도달 할 때까지 자손을 돌려 주어야한다. 유감스럽게도 이전 버전과의 호환성을 위해 현재 응용 프로그램에 영향을 미치지 않는 방법으로는이 방법을 사용하지 않을 것입니다.
그러나 ChildNodes
대신 Descendants(0)
사용할 수 있습니다. 코드는 다음과 같습니다.
Console.WriteLine(string.Join("\r\n", lines[0].ChildNodes
.Select(x => $"{x.Name} {x.Id} {(x as HtmlTextNode)?.Text}")));