2013-02-27 62 views
2

在我的Selenium应用程序中,我尝试选择具有最高z-index的元素。该值不是在元素本身中定义的,而是在祖先节点上定义的(嵌套级别未知)。另外,如果通过使用display: none不可见祖先,则不应退回。使用XPath选择具有最高z索引的元素

例HTML:

<div class="container" style="z-index: 10"> 
    <div style="display: none"> 
     <!-- this should not be selected because it is invisible (and the z-index is lower than the others) --> 
     <div myattr="example"></div> 
    </div> 
    </div> 
    <div class="container" style="z-index: 100"> 
    <div> 
     <!-- this should not be selected because the z-index is lower than the others --> 
     <div myattr="example"></div> 
    </div> 
    </div> 
    <div class="container" style="z-index: 1000"> 
    <div> 
     <!-- this should be selected because it is visible and has the highest z-index --> 
     <div myattr="example"></div> 
    </div> 
    </div> 

目前我有一个正则表达式与myattr="example"选择所有元件,其不具有与display: none一个祖先:

//div[@myattr='example' 
and not(ancestor::div[contains(@style,'display:none')]) 
and not(ancestor::div[contains(@style,'display: none')])] 

我需要一个附加条件来选择元件其中Z指数最高,可以说是在其他顶部可见的。对于每个找到的节点,必须查看所有祖先,直到找到具有特定类的节点(本例中为container)。然后只返回z-index祖先最高的元素。

这甚至可能与XPath?

+1

仅供参考,我将最初请求的XPath 1.0解决方案添加到我的答案中,以证明它可以做到:)。 – 2013-06-20 10:09:54

回答

1

我非常努力地尝试,但我认为您无法通过单个XPath 1.0表达式实现此目标。你可以靠近,但不是那里。

您需要使用其他逻辑。有一千种不同的方法。

例如,让所有的container元素,通过z-index对它们进行排序,并测试他们的myattr="example"后裔能见度:

// Gets all containers - could also be Gets all elements containing z-index 
List<WebElement> containers = driver.findElements(By.className("container")); 

// Sorts the containers in an descending order by their z-indexes 
Collections.sort(containers, Collections.reverseOrder(new Comparator<WebElement>() { 
    @Override 
    public int compare(WebElement o1, WebElement o2) { 
     return getZindex(o1) - getZindex(o2); 
    } 
    private int getZindex(WebElement elem) { 
     String zindex = elem.getAttribute("style").toLowerCase().replace("z-index: ", ""); 
     return Integer.parseInt(zindex); 
    } 
})); 

// look for a visible candidate to return as a result 
for (WebElement container : containers) { 
    WebElement result = container.findElement(By.cssSelector("*[myattr='example']")); 
    if (result.isDisplayed()) { 
     return result; 
    } 
} 
throw new IllegalStateException("No element found."); 

编辑:你接受了这个答案后,我回到了问题并提出了一个XPath 1.0解决方案。它太丑陋了,表现不佳,我无法验证其正确性(它适用于您的示例以及其他一些我尝试过的示例),所以我建议您使用上面的WebDriver方法。无论如何,我会分享:

Copypastable oneliner:

//div[@myattr='example' and not(ancestor::div[contains(@style,'display: none')])]/ancestor::div[@class='container' and substring-after(@style,'z-index:') > substring-after(../div[not(descendant::div[contains(@style,'display: none')])]/@style,'z-index:')] 

格式化版本:(!不是文字之一)

//div 
    [ 
     @myattr='example' 
     and not(ancestor::div[contains(@style,'display: none')]) 
    ] 
    /ancestor::div 
     [ 
      @class='container' 
      and substring-after(@style,'z-index:') 
       > substring-after(
        ../div[not(descendant::div[contains(@style,'display: none')])]/@style, 
        'z-index:') 
     ] 

和免费翻译人类的语言:

SELECT A VISIBLE <div @myattr='example'> NODE 
//div 
    [ 
     @myattr='example' 
     and not(ancestor::div[contains(@style,'display: none')]) 
    ] 
    THAT HAS A <div @class='container'> ANCESTOR 
    /ancestor::div 
     [ 
      @class='container' 
      WHOSE z-index IS GREATER THAN z-index... 
      and substring-after(@style,'z-index:') 
       > substring-after(
        ...OF ALL VISIBLE SIBLINGS 
        ../div[not(descendant::div[contains(@style,'display: none')])]/@style, 
        'z-index:') 
     ] 
+0

非常感谢这个编辑,非常有洞察力 – Alp 2013-06-20 10:21:08

+1

@Alp呵呵,顺便说一下,它选择容器,所以'// div [如果你想选择内部元素,应该附加@ myattr ='example']。 – 2013-06-20 10:27:35

1

我以为你知道的z-index的最高值,在这种情况下,XPath是

"//div[contains(@style,'1000')]/div[not(contains(@style,'none'))]/div" 

否则使用下面的XPath获得股利

List<WebElement> divTags=driver.findElements(By.xpath("//div[not(contains(@style,'none'))]/parent::div[contains(@style,'z-index')]")) 
for(WebElement ele:divTags) 
{ 
    ele.getAttribute("style"); 
} 
  • 商店在Z的所有样式属性某些变量的索引
  • 解析存储的z索引并单独获取数字
  • 使用一些逻辑查找其中的最高数字
  • 做所有上述事情都对这些元素的索引有效。
  • 找到最高的z-index后,得到该元素的索引
  • 使用该索引构建xpath。

我希望上面的逻辑能帮助你实现你的目标。

+0

可悲的是我不知道最高的z-index,因为代码是动态生成的(qooxdoo) – Alp 2013-02-27 17:28:43