ASP.NET中Html Agility Pack是否有jQuery .nextUntil的等效方法?
用Html Agility Pack实现类似jQuery的
.nextUntil()功能 嘿,好问题!Html Agility Pack(HAP)本身并没有内置和jQuery的.nextUntil()完全等效的方法,但咱们可以轻松自己写一个扩展方法来复刻这个功能,完全贴合你想要的行为。
先回忆下jQuery的.nextUntil():它会获取当前元素之后的所有同级元素,直到遇到指定的“停止元素”为止(不包含停止元素本身),同时会跳过文本、注释这类非元素节点,只返回元素节点。咱们的扩展方法就按照这个逻辑来实现。
实现扩展方法
下面是两个重载的扩展方法,分别对应jQuery中“按选择器停止”和“按节点停止”的两种用法:
using HtmlAgilityPack; using System; using System.Collections.Generic; using System.Linq; public static class HtmlNodeExtensions { // 按CSS选择器匹配停止节点 public static IEnumerable<HtmlNode> NextUntil(this HtmlNode node, string stopSelector) { if (node == null) throw new ArgumentNullException(nameof(node)); if (string.IsNullOrWhiteSpace(stopSelector)) throw new ArgumentException("停止选择器不能为空或空白", nameof(stopSelector)); var currentNode = node.NextSibling; while (currentNode != null) { // 如果当前节点匹配停止选择器,立刻终止遍历 if (currentNode.IsMatch(stopSelector)) break; // 只返回元素节点(和jQuery一致,跳过文本、注释等) if (currentNode.NodeType == HtmlNodeType.Element) yield return currentNode; currentNode = currentNode.NextSibling; } } // 按指定节点停止遍历 public static IEnumerable<HtmlNode> NextUntil(this HtmlNode node, HtmlNode stopNode) { if (node == null) throw new ArgumentNullException(nameof(node)); if (stopNode == null) throw new ArgumentNullException(nameof(stopNode)); var currentNode = node.NextSibling; while (currentNode != null && !currentNode.Equals(stopNode)) { if (currentNode.NodeType == HtmlNodeType.Element) yield return currentNode; currentNode = currentNode.NextSibling; } } }
使用示例
假设你有这样的HTML结构:
<div class="content"> <h3>Section 1</h3> <p>First paragraph in section 1</p> <ul> <li>List item 1</li> <li>List item 2</li> </ul> <h3>Section 2</h3> <p>First paragraph in section 2</p> </div>
你想获取第一个<h3>之后到第二个<h3>之前的所有元素,可以这么用:
var htmlDoc = new HtmlDocument(); htmlDoc.LoadHtml(yourHtmlContent); // 获取第一个h3节点 var firstSectionHeader = htmlDoc.DocumentNode.SelectSingleNode("//h3[1]"); // 获取两个h3之间的所有元素 var elementsInSection1 = firstSectionHeader.NextUntil("h3"); // 遍历输出结果 foreach (var node in elementsInSection1) { Console.WriteLine(node.OuterHtml); // 会输出<p>和<ul>的完整HTML }
如果已经拿到了停止节点的引用,也可以用第二个重载:
var secondSectionHeader = htmlDoc.DocumentNode.SelectSingleNode("//h3[2]"); var elementsInSection1 = firstSectionHeader.NextUntil(secondSectionHeader);
小提示
- 如果需要包含停止节点,只需要在遇到停止节点时先返回它,再终止遍历即可。
IsMatch()方法是HAP自带的CSS选择器匹配方法,确保你使用的是较新版本的Html Agility Pack(旧版本可能需要额外引用选择器包)。
内容的提问来源于stack exchange,提问作者Hassam Munir
相关产品推荐
相关产品推荐

