XPath-在两个节点之间提取文本

XPath-在两个节点之间提取文本,xpath,Xpath,我的XPath查询遇到了一个问题。我必须解析一个div,它被划分为未知数量的“部分”。每一个都用h5和一个节名隔开。可能的章节标题列表是已知的,每个标题只能出现一次。此外,每个部分可以包含一些br标记。假设我想提取“SecondHeader”下的文本 HTML 问题#1 结果#1 这显然有点太多了,所以我决定将结果限制在所选标题和之前标题之间的内容 问题2 结果#2 取得的成果符合预期。然而,这不能被使用-我不知道在解析的页面中是否存在SecondHeader/ThirdHeader。在查询中只

我的XPath查询遇到了一个问题。我必须解析一个div,它被划分为未知数量的“部分”。每一个都用h5和一个节名隔开。可能的章节标题列表是已知的,每个标题只能出现一次。此外,每个部分可以包含一些br标记。假设我想提取“SecondHeader”下的文本

HTML

问题#1

结果#1

这显然有点太多了,所以我决定将结果限制在所选标题和之前标题之间的内容

问题2

结果#2

取得的成果符合预期。然而,这不能被使用-我不知道在解析的页面中是否存在SecondHeader/ThirdHeader。在查询中只需要使用一个节标题

问题3

结果#3


你能告诉我我做错了什么吗?我已经在Google Chrome上测试过了。

如果所有
h5
元素和文本节点都是兄弟节点,并且您需要按节进行分组,那么一个可能的选项就是只需按前面的
h5
计数来选择文本节点

使用
lxml
(Python中)的示例

导入lxml.html >>>s=''' ... ... 第一头 ... 文本1 ... 第二标题 ... text2a
... text2b ... 第三头 ... text3a
... text3b
... text3c
... 第四收割台 ... 文本4 ... ''' >>>doc=lxml.html.fromstring >>>doc.xpath(“//text()[count(前面的同级::h5)=$count]”,count=1) ['\n text1\n'] >>>doc.xpath(“//text()[count(前面的同级::h5)=$count]”,count=2) ['\n text2a','\n text2b\n'] >>>doc.xpath(“//text()[count(前面的同级::h5)=$count]”,count=3) ['\n text3a'、'\n text3b'、'\n text3c'、'\n'] >>>doc.xpath(“//text()[count(前面的同级::h5)=$count]”,count=4) ['\n text4\n'] >>>
您应该能够只测试前面的第一个兄弟姐妹
h5

//text()[preceding-sibling::h5[1][normalize-space()='SecondHeader']]
['text2a', 'text2b']
//text()[following-sibling::h5/text()='ThirdHeader']
['text1', 'text2a', 'text2b']
//text()[following-sibling::h5/text()='ThirdHeader' and preceding-sibling::h5/text()='SecondHeader']
['text2a', 'text2b']
//text()[following-sibling::h5/text()='ThirdHeader' and not[preceding-sibling::h5/text()='ThirdHeader']]
[]
>>> import lxml.html
>>> s = '''
... <div class="some-class">
...  <h5>FirstHeader</h5>
...   text1
...  <h5>SecondHeader</h5>
...   text2a<br>
...   text2b
...  <h5>ThirdHeader</h5>
...   text3a<br>
...   text3b<br>
...   text3c<br>
...  <h5>FourthHeader</h5>
...   text4
... </div>'''
>>> doc = lxml.html.fromstring(s)
>>> doc.xpath("//text()[count(preceding-sibling::h5)=$count]", count=1)
['\n  text1\n ']
>>> doc.xpath("//text()[count(preceding-sibling::h5)=$count]", count=2)
['\n  text2a', '\n  text2b\n ']
>>> doc.xpath("//text()[count(preceding-sibling::h5)=$count]", count=3)
['\n  text3a', '\n  text3b', '\n  text3c', '\n ']
>>> doc.xpath("//text()[count(preceding-sibling::h5)=$count]", count=4)
['\n  text4\n']
>>> 
//text()[preceding-sibling::h5[1][normalize-space()='SecondHeader']]