2011-11-30 213 views
5

我使用Selenium 2.12。使用WebDriver API,假設我有一個代表表格的WebElement(<table>)。使用該元素,我如何選擇第一列中的所有td?我假設這裏有一個xpath表達式。如何選擇Selenium webdriver中的所有列第一個單元格(tds)?

爲了更好地瞭解表結構,如果我從我的tableElement WebElement ...

String html = (String)((JavascriptExecutor)driver).executeScript("return arguments[0].innerHTML;", tableElt); 

得到HTML我得到下面的混亂。要注意的關鍵問題是,有6周TR的16 TD的...

<thead><tr><th colspan="1" class="GCSPOWVGE GCSPOWVEE GCSPOWVEF GCSPOWVFF"><div style="padding-left: 17px;position:relative;zoom:1;"><div style="left:0px;margin-top:-4px;position:absolute;top:50%;line-height:0px;"><img onload='this.__gwtLastUnhandledEvent="load";' src="http://localhost:9080/cme-productplus-web/productplus/clear.cache.gif" style="width: 11px; height: 7px; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAHCAYAAADebrddAAAAiklEQVR42mNgwALyKrumFRf3iDAQAvmVXVVAxf/zKjq341WYV95hk1fZ+R+MK8C4HqtCkLW5FZ2PQYpyK6AaKjv/5VV1OmIozq3s3AFR0AXFUNMrO5/lV7WKI6yv6mxCksSGDyTU13Mw5JV2qeaWd54FWn0BRAMlLgPZl/NAuBKMz+dWdF0H2hwCAPwcZIjfOFLHAAAAAElFTkSuQmCC) no-repeat 0px 0px;" border="0"></div><div>GUID</div></div></th><th colspan="1" class="GCSPOWVGE GCSPOWVEF">Fung Ratio</th><th colspan="1" class="GCSPOWVGE GCSPOWVEF">Fung type</th><th colspan="1" class="GCSPOWVGE GCSPOWVEF">Fung Date Offset</th><th colspan="1" class="GCSPOWVGE GCSPOWVEF GCSPOWVOE">Days To Retain</th></tr></thead><colgroup><col><col><col><col><col></colgroup><tbody><tr onclick="" class="GCSPOWVAE"><td class="GCSPOWVPD GCSPOWVBE GCSPOWVCE"><div style="outline:none;" tabindex="0">  DSSUAQR6IE6E </div></td><td class="GCSPOWVPD GCSPOWVBE"><div style="outline:none;">  10  </div></td><td class="GCSPOWVPD GCSPOWVBE"><div style="outline:none;">    </div></td><td class="GCSPOWVPD GCSPOWVBE"><div style="outline:none;">  </div></td><td class="GCSPOWVPD GCSPOWVBE GCSPOWVME"><div style="outline:none;">   </div></td></tr><tr onclick="" class="GCSPOWVAF"><td class="GCSPOWVPD GCSPOWVBF GCSPOWVCE"><div style="outline:none;">  ETTUAQR6IE6E </div></td><td class="GCSPOWVPD GCSPOWVBF"><div style="outline:none;">  30  </div></td><td class="GCSPOWVPD GCSPOWVBF"><div style="outline:none;">    </div></td><td class="GCSPOWVPD GCSPOWVBF"><div style="outline:none;">  </div></td><td class="GCSPOWVPD GCSPOWVBF GCSPOWVME"><div style="outline:none;">   </div></td></tr><tr onclick="" class="GCSPOWVAE"><td class="GCSPOWVPD GCSPOWVBE GCSPOWVCE"><div style="outline:none;">  FCCUAQR6IE6E </div></td><td class="GCSPOWVPD GCSPOWVBE"><div style="outline:none;">  20  </div></td><td class="GCSPOWVPD GCSPOWVBE"><div style="outline:none;">    </div></td><td class="GCSPOWVPD GCSPOWVBE"><div style="outline:none;">  </div></td><td class="GCSPOWVPD GCSPOWVBE GCSPOWVME"><div style="outline:none;">   </div></td></tr></tbody><tbody style="display: none;"><tr><td colspan="5" align="center"><div><div style="width: 100%; height: 100%; padding: 0px; margin: 0px; display: none;"><div style="width: 100%; height: 100%; display: none;"></div></div><div style="width: 100%; height: 100%; padding: 0px; margin: 0px; display: none;"><div class="GCSPOWVPE" style="width: 100%; height: 100%; display: none;"><img class="gwt-Image" onload='this.__gwtLastUnhandledEvent="load";' src="http://localhost:9080/cme-productplus-web/productplus/clear.cache.gif" style="width: 43px; height: 11px; background: url(data:image/gif;base64,R0lGODlhKwALAPEAAP///0tKSqampktKSiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAKwALAAACMoSOCMuW2diD88UKG95W88uF4DaGWFmhZid93pq+pwxnLUnXh8ou+sSz+T64oCAyTBUAACH5BAkKAAAALAAAAAArAAsAAAI9xI4IyyAPYWOxmoTHrHzzmGHe94xkmJifyqFKQ0pwLLgHa82xrekkDrIBZRQab1jyfY7KTtPimixiUsevAAAh+QQJCgAAACwAAAAAKwALAAACPYSOCMswD2FjqZpqW9xv4g8KE7d54XmMpNSgqLoOpgvC60xjNonnyc7p+VKamKw1zDCMR8rp8pksYlKorgAAIfkECQoAAAAsAAAAACsACwAAAkCEjgjLltnYmJS6Bxt+sfq5ZUyoNJ9HHlEqdCfFrqn7DrE2m7Wdj/2y45FkQ13t5itKdshFExC8YCLOEBX6AhQAADsAAAAAAAAAAAA=) no-repeat 0px 0px;" border="0"></div></div></div></td></tr></tbody><tfoot style="display: none;"><tr><th colspan="5" class="GCSPOWVFE GCSPOWVDE GCSPOWVNE"></th></tr></tfoot> 

可悲的是,這兩個表達式不產生正確的結果。

 // This returns zero td's 
     final List<WebElement> tds = tableElt.findElements(By.xpath("/tr/td[1]")); 

     ... 

     // This returns 238 td's (I think that's everything in my document) 
     final List<WebElement> tds = tableElt.findElements(By.xpath("//td[1]")); 

回答

4

要使用的確切表達式取決於文檔的實際結構。

在最一般的情況下 - 在選擇所有從表中的第一列單元的 - 你可以使用下面的表達式:

<path_to_table>//td[1] 

例如,本文件:

<table> 
    <tr> 
     <td>1</td> 
     <td>2</td> 
     <td>3</td> 
     <td>4</td> 
    </tr> 
    <tr> 
     <td>a</td> 
     <td>b</td> 
     <td>c</td> 
     <td>d</td> 
    </tr> 
    <tr> 
     <td>i</td> 
     <td>ii</td> 
     <td>iii</td> 
     <td>iv</td> 
    </tr> 
</table> 

該表達式:

/table//td[1] 

給出:

<td>1</td> 
<td>a</td> 
<td>i</td> 

請注意,我使用的是後代或自我軸(//),因爲HTML表格允許使用可選的分組元素(例如, <tbody>),其可能存在也可能不存在。但是,這也包括嵌套表格的第一列單元格。考慮此輸入:

<table> 
    <tr> 
     <td>1</td> 
     <td><table><td>test</td></table></td> 
     <td>3</td> 
     <td>4</td> 
    </tr> 
    <tr> 
     <td>a</td> 
     <td>b</td> 
     <td>c</td> 
     <td>d</td> 
    </tr> 
    <tr> 
     <td>i</td> 
     <td>ii</td> 
     <td>iii</td> 
     <td>iv</td> 
    </tr> 
</table> 

同樣的表情從以上的回報:

<td>1</td> 
<td>test</td> 
<td>a</td> 
<td>i</td> 

如果你知道更多關於你的具體的表結構,那麼你可以寫一個更具體的表達。例如,在前面的輸入,這個表達式:

/table/tr/td[1] 

...返回從最外層的表只有細胞:

<td>1</td> 
<td>a</td> 
<td>i</td> 
+0

什麼表達式我需要寫,如果我有一個已經p的WebElement有問題的桌子上有點油?所以,這將是類似tableElement.findElement(By.xpath(「...」))謝謝, - Dave – Dave

+0

@Dave - 在這種情況下,它可能類似'/ tr/td [1]'或'// td [1]',具體取決於表結構 –

+0

嗨,可悲的是每個表達式都沒有得到正確的結果。我編輯我的響應,以包含WebElement中的表結構。雖然這是一團糟,但我認爲第一個表達式(/ tr/td [1])在調用時返回零個元素,「最終列表 tds = tableElt.findElements(By.xpath(」/ tr/td [1] 「));」。第二個返回238,這是我的HTML文檔中的每個td,而不僅僅是table元素中的td。 – Dave

1

如果每個tr包含td同等數量可以形成一個列表使用.findElements(By.tagName("td"))並通過該列表的每第n個元素,其中迭代n等於td元件的在每個tr

數所有 td元件3210
+0

我和這個人在一起。代碼可能不起作用,但你明白了。 獲取所有td或tr元素,並在java代碼中處理它們,這與xpath相比非常快。 – hennr

0

如果您已經將表格存儲爲WebElement,那麼您所需要做的就是像WebDriver一樣解析WebElement。

//The first part is just a reference for others to see the table element being caught 
WebElement TableElement = driver.findElement(By.tagName("table")); 

這將創建TD元素的列表(你應該使用XPath,你想要的特定元素中的XPath往往是一點就慢側,您可以指定元素和國家相關的XPath所以如果你解析一個大的頁面,你可能想要去與CssSelector:首個類型

List<WebElement> FirstColumns = TableElement.findElements(By.xPath("//tr/td[1]")); 
6
// This returns 238 td's (I think that's everything in my document)    
    final List<WebElement> tds = tableElt.findElements(By.xpath("//td[1]")); 

這也正是按照THW的XPath W3C規範,是第m一個XPath中的常見問題解答。

//僞操作符的優先級(優先級)小於[]操作符的優先級(優先級)。

因此,//SomeName[1]選擇所有名爲SomeName的元素,它們的父級的第一個SomeName子元素 - 並且可能會有很多這樣的元素。

如果你想選擇XML文檔中的第一個SomeName元素,你需要使用括號明確地覆蓋默認的運算符優先級:

(//SomeName)[1] 

在這種情況下,你只需要第一td後裔給定的元素 - 因此除了上述修正之外,您必須更正您的表達爲相對 - 不是絕對的。一個絕對的XPath表達式(始於/始終被評估爲具有文檔節點的附屬上下文節點)。

使用

(.//td)[1] 

如果需要選擇當前節點的所有td後代,然後用:

.//td 

更妙的是:

.//descendant::td 
+0

這是迄今爲止最接近的答案。表達方式 (。// td)[1]僅返回第一個td單元格,而不是第一列中的所有單元格,這正是我想要的。謝謝, - – Dave

+0

@Dave:哦,然後就是使用:'.// td' –

+0

@Dave:我更新了我的回答並回復了您的評論。 –

相關問題