如何使用HTML Agility Pack解包嵌套div并提取内部元素
实现嵌套空div解包的解决方案
核心思路
要实现多层嵌套div的扁平化,需要从最内层的div开始向上处理,避免外层节点修改导致遍历失效:
- 倒序遍历所有div节点(优先处理深层节点)
- 过滤子节点中的空白文本后,判断当前div是否仅包含div类型的子元素(即没有实际内容节点)
- 符合条件的话将该div的所有子节点迁移到父节点下,再删除当前冗余div
完整实现代码
using HtmlAgilityPack; // 此处替换为你实际的HTML内容,注意原示例中<p>标签闭合为</span>属于笔误,已修正 var html = @"<div> <div> <div> <div> <span>Test 1</span> <p>Test 2</p> </div> </div> </div> </div>"; var htmlDoc = new HtmlDocument(); htmlDoc.LoadHtml(html); // 先获取所有div节点转为列表,倒序遍历避免节点修改导致遍历异常 var allDivs = htmlDoc.DocumentNode.Descendants("div").ToList(); for (int i = allDivs.Count - 1; i >= 0; i--) { var currentDiv = allDivs[i]; // 过滤掉空白文本节点,判断剩余有效子节点类型 var validChildren = currentDiv.ChildNodes .Where(n => n.NodeType != HtmlNodeType.Text || !string.IsNullOrWhiteSpace(n.InnerText)) .ToList(); // 仅当当前div的有效子节点全是div、或本身是无内容的空div时做解包处理 if (validChildren.All(n => n.Name == "div") || validChildren.Count == 0) { // 把子节点全部移到父节点下,放在当前div的前面 foreach (var child in currentDiv.ChildNodes.ToList()) { currentDiv.ParentNode.InsertBefore(child, currentDiv); } // 删除冗余的当前div currentDiv.Remove(); } } // 输出处理后的结果 Console.WriteLine(htmlDoc.DocumentNode.OuterHtml);
运行输出
处理后的HTML和期望结果完全一致:
<div> <span>Test 1</span> <p>Test 2</p> </div>
内容的提问来源于stack exchange,提问作者Speeds
相关产品推荐
相关产品推荐

