2012-05-17 28 views
12

Chcę pobrać dane z tabel w interfejsie użytkownika. Wiem o przepuszczaniu wierszy i kolumn za pomocą "tr" i "td". Ale jedna tabela mam jest coś takiego:Selenium Webdriver - Pobieranie danych tabeli

<table> 
<tbody> 
    <tr><td>data</td><th>data</th><td>data</td><td>data</td></tr> 
    <tr><td>data</td><th>data</th><td>data</td><td>data</td></tr> 
    <tr><td>data</td><th>data</th><td>data</td><td>data</td></tr> 
</tbody> 
</table> 

Jak mogę uczynić mój kod ogólny, tak że występowanie „TH” w środku mogą być obsługiwane. Obecnie używam tego kodu:

// Grab the table 
WebElement table = driver.findElement(By.id(searchResultsGrid)); 

// Now get all the TR elements from the table 
List<WebElement> allRows = table.findElements(By.tagName("tr")); 
// And iterate over them, getting the cells 
for (WebElement row : allRows) { 
List<WebElement> cells = row.findElements(By.tagName("td")); 
for (WebElement cell : cells) { 
// And so on 
} 
} 

Odpowiedz

14

można spojrzeć na wszystkie dzieci tr elementu bez rozróżniania td i th. Więc zamiast

List<WebElement> cells = row.findElements(By.tagName("td")); 

użyłbym

List<WebElement> cells = row.findElements(By.xpath("./*")); 
+0

Ale to daje wszystkie dzieci w tym linków lub wejścia itp wewnątrz – Sky

+0

nie bardzo. Mój przykład zwróciłby tylko dzieci pierwszego poziomu. Oznacza to tylko znaczniki tr i th (w odniesieniu do przykładu). Elementy pomiędzy i (innymi słowy cokolwiek z "danych" z twojego przykładu) ** nie zostaną zwrócone. – JacekM

+0

@Sky - Dostarczona ścieżka xpath dostanie tylko dzieci, a nie potomków. –

8

Mayby to zbyt późno dla właściciela to pytanie, ale pomocne dla innych.

List<WebElement> cells = row.findElements(By.xpath(".//*[local-name(.)='th' or local-name(.)='td']")); 
0

tak to działa dla C# z selenem ...

IList<IWebElement> cells = row.findElements(By.xpath(".//*[local-name(.)='th' or local-name(.)='td']")); 
3
// Grab the table 
WebElement table = driver.findElement(By.id("searchResultsGrid")); 

// Now get all the TR elements from the table 
List<WebElement> allRows = table.findElements(By.tagName("tr")); 
// And iterate over them, getting the cells 
for (WebElement row : allRows) { 
    List<WebElement> cells = row.findElements(By.tagName("td")); 
    for (WebElement cell : cells) { 
     System.out.println("content >> " + cell.getText()); 
    } 
} 

użyciu cell.getText() po prostu pracować

0
IWebElement table = driver.FindElement(By.Id("id")); 
List<IWebElement> allRows = new List<IWebElement> (table.FindElements(By.TagName("tr"))); 

foreach (var Row in allRows) 
{ 
    List<IWebElement> cells = new List<IWebElement>(Row.FindElements(By.TagName("td"))); 
    foreach (var cel in cells) 
    { 
     string test = cel.Text; 
    } 
} 
+0

to działa w C# –

2

Nie trzeba pętli elementów. Zamiast tego użyj lokalizatora CoChained.

Jeśli tabela wygląda następująco:

<table> 
    <tbody> 
    <tr><th>Col1</th><th>Col2</th><th>Col3</th></tr> 
    <tr><td>data</td><td>data</td><td>data</td></tr> 
    <tr><td>data</td><td>data</td><td>data</td></tr> 
    <tr><td>data</td><td>data</td><td>data</td></tr> 
    </tbody> 
</table> 

zlokalizować tak:

By tableBodyLocator = By.xpath(".//table/tbody"); 
By headerRowLocator = By.xpath(".//tr[position()=1]"); 
By dataRowsLocator = By.xpath(".//tr[not(position()=1)]"); 

By headerRowLocator = new ByChained(tableBodyLocator, headerRowLocator); 
List<WebElement> weHeaders = driver.findElement(headerRowLocator) 
     .findElements(By.xpath(".//th"); 
List<WebElement> allRowData = driver.findElements(tableBodyLocator, dataRowsLocator); 

WebElement row1Data = allRowData.get(0); 
WebElement row2Data = allRowData.get(1); 

etc. 
0

poniższy kod nie można dostać tylko wiersze i kolumny tabeli, ale również można dostać Kolejność, w jakiej są one w przeglądarce, jest szczególnie przydatna, jeśli masz struktury zagnieżdżone w kolumnie TD, tak jak w twoim przypadku.

public DataTable StoreHtmlTableToDataTable(IWebElement tblObj,bool isFirstRowHeader = true) 
     { 
      DataTable dataTbl = new DataTable(); 
      int rowIndex = 0; 

      try 
      {    
       //_tblDataCollection = new List<TableDataCollection>(); 

       var tblRows = ((IJavaScriptExecutor)DriverContext.Driver).ExecuteScript("return arguments[0].rows; ", tblObj); 

       if (tblRows != null) 
       { 
        //Iterate through each row of the table 
        foreach (IWebElement tr in (IEnumerable)tblRows) 
        {       
         int colIndx = 0; 
         DataRow dtRow = dataTbl.NewRow(); 
         // Iterate through each cell of the table row 
         var tblCols = ((IJavaScriptExecutor)DriverContext.Driver).ExecuteScript("return arguments[0].cells; ", tr); 
         foreach (IWebElement td in (IEnumerable)tblCols) 
         { 
          //add the header row of the table as the datatable column hader row 
          if (rowIndex == 0) 
          { 
           dataTbl.Columns.Add("Col" + colIndx.ToString(), typeof(string)); 
          } 

          dtRow["Col"+colIndx.ToString()] = td.Text; 

          //loop through any child or nested table structures if you want using the same approach for example links,radio buttons etc inside the cell 

          //Write Table to List : This part is not done yet       
          colIndx++; 
         } 
         dataTbl.Rows.Add(dtRow); 
         rowIndex++; 
        } 

       } 


      } 
      catch (Exception) 
      { 
       throw; 
      } 

      //if first row is the header row then assign it as a header of the datatable 
      if (isFirstRowHeader) 
      { 
       dataTbl = this.AssignDataTableHeader(dataTbl); 
      } 

      return dataTbl; 
     } 
Powiązane problemy