首页 > 解决方案 > HtmlAgilityPack - XPath:选择特定节点之后的节点序列,直到具有特定后代的节点

问题描述

我想使用 XPath 选择包含强子标签的 ap 标签,并将其作为键值对中的键。我想要跟随 p 标签的值,直到它到达下一个强标签。

不幸的是,我正在处理的 HTML 不是我自己的,所以我无法修改它的结构以使其更简单。如果文本已知,我会看到几个以这种方式使用 XPath 的示例,但在这种情况下,特定文本是可变的。

这是简化的 HTML 的相关部分:

<div class="div_1"> 
 <div class="div_2">
   <p><em><strong>Title 1</strong></em> Some Text</p>
   <p>Some Text <a class="tooltip">Some Text</a></p>
   <p>Some Text <a class="tooltip">Some Text</a></p>
   <p>Some Text <a class="tooltip">Some Text</a></p>
   <p><em><strong>Title 2</strong></em> Some Text.</p>                
  </div>
</div>

这是我在 VB 中尝试的方法:

For Each trait_head As HtmlAgilityPack.HtmlNode In content.DocumentNode.SelectNodes(
        "//div[@class='div_1']/div[@class='div_2']/p/em/strong")
            trait_heading = trait_head.InnerText
            trait_heading = trait_heading.Trim().Replace(vbCr, "").Replace(vbLf, "")
            For Each trait_bod As HtmlAgilityPack.HtmlNode In content.DocumentNode.SelectNodes(
            "//div[@class='div_1']/div[@class='div_2']/p")
                If trait_body Is Nothing Then
                    trait_body = trait_bod.InnerText
                Else
                    trait_body = trait_body & vbCr & vblf & trait_bod.InnerText
                End If
            Next
trait_value.add(New KeyValuePair(Of String, String)(trait_heading, trait_body))
Next 

所以我需要修改的是第二个 XPath 语句,以便 for 循环在遇到第二个 p 标记时中断。

寻找这个结果:
trait_value = "Title 1" => "Some text vbcr vblf Some text vbcr vblf Some text vbcr vblf Some text vbcr vblf","Title 2" => "Some text"

希望我在这里问的只是使用 XPath 是可能的,但是如果有人对完全不同的方法提出建议,我会很高兴听到他们的意见。

标签: vb.netxpathhtml-agility-pack

解决方案


最后结果:

For Each trait_head As HtmlAgilityPack.HtmlNode In content.DocumentNode.SelectNodes(
        "//div[@class='div_1']/div[@class='div_2']/p/em/strong")
            trait_heading = trait_head.InnerText
            trait_heading = trait_heading.Trim().Replace(vbCr, "").Replace(vbLf, "")
            For Each trait_bod As HtmlAgilityPack.HtmlNode In content.DocumentNode.SelectNodes(
            "//div[@class='div_1']/div[@class='div_2']/p[em/strong]")
                If trait_body Is Nothing Then
                    trait_body = trait_bod.LastChild
                Else
                    trait_body = trait_body & vbCr & vblf & trait_bod.LastChild
                End If
            Next
trait_value.add(New KeyValuePair(Of String, String)(trait_heading, trait_body))
Next

推荐阅读