HtmlAgilityPack - XPath: выберите последовательность узлов после определенного узла до узла с определенным потомком - PullRequest
0 голосов
/ 08 января 2019

Я хочу использовать XPath, чтобы выбрать тег p, который содержит сильный дочерний тег, и поместить его в качестве ключа в пару ключ-значение. Значение, за которым я хочу следить за тегами 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" => "Некоторый текст vbcr vblf Некоторый текст vbcr vblf Некоторый текст vbcr vblf Некоторый текст vbcr vblf", "Title 2" => "Некоторый текст"

Надеюсь, то, что я здесь прошу, возможно только при использовании XPath, но если у кого-то есть предложения по другому подходу, я был бы рад их услышать.

1 Ответ

0 голосов
/ 08 января 2019

Окончательный результат:

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
...