如何在不使用非动态位置的情况下选择动态受限的节点范围?

时间:2016-06-01 23:58:05

标签: html xml selenium xpath

<li></li>
  <th>
<li></li>
  <strong>"Jeff"<strong>
<li></li>
  <a>"Mary"<a>
<li></li>
  <th>
<li></li>
  <strong>"Rich"<strong>
<li></li>
  <strong>"Alex"<strong>
<li></li>
  <a>"Bob"<a>
<li></li>
  <th>
<li></li>
  <strong>"Dave"<strong>
<li></li>
  <a>"Joseph"<a>
<li></li>
  <th>

我需要在xpath中使用“Jeff”选择包含“Jeff”和“Mary”的所有列表项,而不选择任何其他内容而不使用非动态位置。

示例:

//li[following-sibling::li/strong[contains(text() , "Jeff")]]/following-sibling::li[th][1]/preceding-sibling::li[not(th)]

这适用于第一组(Jeff和Mary),但是一旦应用到代码中的范围之后,它就会崩溃并开始选择超过需要的范围。

示例:

//li[following-sibling::li/strong[contains(text() , "Rich")]]/following-sibling::li[th][1]/preceding-sibling::li[not(th)]

选择“Rich”,“Alex”,“Bob”......还有“Jeff”和“Mary”

示例:

//li[following-sibling::li/strong[contains(text() , "Dave")]]/following-sibling::li[th][1]/preceding-sibling::li[not(th)]

选择“Dave”和“Joseph”,还选择“Rich”,“Alex”,“Bob”,“Jeff”和“Mary”。

我希望能够插入一个名称,并且有一个表达式可以选择包含该名称的列表项的兄弟列表的所有列表项,但是一旦它到达包含标题的列表项,它也会停止选择。问题似乎在于带有标题的列表项在任何方面都不是唯一的。这是xpaths不能做的事情吗?

1 个答案:

答案 0 :(得分:2)

您的示例HTML不是格式良好的XML,但许多元素缺少结束标记。请考虑以下格式良好的XML样本:

<div> 
  <li/>  
  <th> 
    <li/>  
    <strong>"Jeff"</strong>  
    <li/>  
    <a>"Mary"</a>  
    <li/> 
  </th>  
  <li/>  
  <strong>"Rich"</strong>  
  <li/>  
  <strong>"Alex"</strong>  
  <li/>  
  <a>"Bob"</a>  
  <li/>  
  <th> 
    <li/>  
    <strong>"Dave"</strong>  
    <li/>  
    <a>"Joseph"</a>  
    <li/> 
  </th> 
</div>

以下XPath返回了'Jeff','Rich'和'Dave'的文本节点的通缉列表:

//li[
    following-sibling::*[1][contains(text(),'put the name here')]
]/following-sibling::*/text()

XPath首先查找<li>,后面跟着包含该名称的元素。然后从找到的<li>中,它从所有以下兄弟元素中返回文本节点。

但是,如果你有另一组名称没有包含在<th>中,那么XPath会失败(目前你只有一组这样的名字,这很好)。例如,您可以添加另一个在<th>之前计数的逻辑来处理这种情况。这将使XPath相当复杂,所以除非实际需要,否则我不会实现它。