我正在使用HtmlAgilityPack来解析和分析HTML页面,我需要知道每个节点的“深度” - 距Body
节点的距离。示例(“深度”属性仅用于说明目的):
<html>
<head></head>
<body depth="0">
<div depth="1">
<ul depth="2">
<li depth="3">
<p depth="4">foo</p>
</li>
<li depth="3">
<p depth="4">bar</p>
</li>
</ul>
</div>
</body>
</html>
我正试图避免两个明显的解决方案:
node.ParentNode
直到达到body
来“按需”计算每个节点的深度。有没有办法通过某种方式使用HtmlAgilityPack在Load
收集的现有数据来避免这些?
答案 0 :(得分:3)
据我所知,AgilityPack不存储节点的深度。
如果你想得到所有节点的深度,假设它更容易编写,例如从根节点开始并通过递归调用当前节点子节点来增加深度的递归方法。
对于单个节点的深度计算,您可以使用HtmlNode.XPath
属性,并计算此值中的斜杠数(/
)。这将是节点深度。在您的情况下,您应首先计算<body>
节点的深度,然后从愿望节点的深度中减去此值以获得相对深度:
var bodyDepth = doc.DocumentNode
.SelectSingleNode("//body")
.XPath
.Count(c => c == '/');
var paragraphDepth = doc.DocumentNode
.SelectSingleNode("//p")
.XPath
.Count(c => c == '/');
var result = paragraphDepth - bodyDepth;
这会给你4
,但我不确定这比迭代ParentNode
属性更容易。
答案 1 :(得分:1)
您在询问是否有内置NodeDepth
属性或类似内容?我非常肯定答案是否定的,因为计算出由库解析的每个节点都会产生很少需要保证的开销。由于通过一些递归很容易计算节点深度,我认为它们不会包含默认值。
为什么要避免使用明显的解决方案?
答案 2 :(得分:0)
HtmlAgilityPack不会给出深度细节。我们可以使用&#39; /&#39;的计数从XPath变量中获取它。上面提供的字符。我们不需要遍历父母以获取详细信息。
foreach (HtmlNode rootNode in document.DocumentNode.Descendants())
{
levels.Add(rootNode.XPath.Count(x => x == '/'));
}
它应该有用。