【发布时间】:2018-12-13 07:50:11
【问题描述】:
我正在使用 HtmlAgilityPack 一次遍历一个级别的文档树。但是,似乎调用node.Descendants(0) 会返回整个节点树。
注意:我尝试粘贴逐字 HTML 字符串,但 SE 解析器不喜欢它,所以我将其添加为 sn-p。
<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 时做错了什么?
#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}")));
【问题讨论】: