2013-02-27 61 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