如何使用htmlagilitypack获取两个包围的HTML元素之间的HTML?

4

我需要用C#的HtmlAgilityPack获取包含在另外两个HTML元素中的元素。

举个例子,我有以下内容:

<div id="div1" style="style definition here">
  <strong>
    <font face="Verdana" size="2">Your search request retrieved 0 matches.</font>
  </strong>
  <font face="Verdana" size="2">Some more text here.</font>
  <br><br>
  <!--more html here-->
</div>

I want to return everything between

<div id="div1">

并且第一件事

<br>

不返回这些元素中的任何一个。

我无法理解所需的语法,因此如果有人可以解释一下在忽略结束标记的情况下获取存在于另外2个已知起始标签之间的html的最佳方法,我将非常感激。

我还应该提到,我需要首先找到id为div1的div,该div位于完整网页的周围html中。

我不需要实际的节点与来自特定HtmlDocument的节点具有引用相等性,它们只需在内容上相同即可。

1个回答

1
当返回HtmlNode实例时,对于同一节点的多次调用将产生相同的引用。您可以利用这一点(尽管这是一个实现细节,所以要小心)。
基本上,您会获取到所有子元素,直到所需节点。您可以选择从哪个节点开始:
HtmlNode divNode = doc.DocumentNode.SelectSingleNode("div[@id='div1']");

您想要上升到的节点:

// Note that in this case, working off the first node is not necessary, just
// convenient for this example.
HtmlNode brNode = divNode.SelectSingleNode("br");

然后在Enumerable类上使用TakeWhile扩展方法,获取第二个元素之前的所有元素,代码如下:
// The nodes.
IEnumerable<HtmlNode> nodes = divNode.Descendants().
    TakeWhile(n => n != brNode).
    Where(n => n.NodeType == HtmlNodeType.Element);

这是与TakeWhile方法相关的比较(n => n != brNode),它依赖于引用比较(这是实现细节的一部分)。

最后一个过滤器是为了只给你元素节点,因为这通常是通过调用SelectSingleNode获得的;如果你想处理其他节点类型,可以省略它。

像这样循环遍历这些节点:

foreach (HtmlNode node in nodes)
{
    // Print.
    Console.WriteLine("Node: {0}", node.Name);
}  

生成:

Node: strong
Node: font
Node: font

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接