find the particular value in the table column - java

i have write the below code for find the particular column value in web table, but if i give the static value in row and column value , driver is identifying the value , but if i get the value through for loop, i am not able to retrieve the values.
WebElement tabledata = driver.findElement(By.id("divAttendanceDetails"));
List<WebElement> Rows = tabledata.findElements(By.xpath("//*[#id='divAttendanceDetails']/table[1]/tbody/tr"));
System.out.println("NoofRowsinthetable" + Rows.size());
String identifyvalue = "Leave Applied";
int leavecount = 0;
for (int getrowvalue=0; getrowvalue < Rows.size()-1;getrowvalue++)
{
List<WebElement> Columns = Rows.get(getrowvalue).findElements(By.xpath("//*[#id='divAttendanceDetails']/table[1]/tbody/tr/td"));
System.out.println("NoofColumnsinthetable" + Columns.size() );
for (int getcolumnvalue =0;getcolumnvalue<Columns.size(); getcolumnvalue++ )
{
String cellvaues = driver.findElement(By.xpath("//*[#id='divAttendanceDetails']/table[1]/tbody/tr["+getrowvalue+"]/td["+getcolumnvalue+"]")).getText();
System.out.println(cellvaues);
if(identifyvalue.equalsIgnoreCase(cellvaues))
{
leavecount = leavecount+1;
System.out.println("Leavecounttilldate" + leavecount );
}
}
}
Please help to resolve the issue
Html Page looks
<div id="newdiv"><table class="ariel" cellspacing="0" cellpadding="3" rules="all" border="1" id="dgResults" style="width:100%;border-collapse:collapse;">
<tbody><tr class="bluerow" align="left" style="font-weight:bold;">
<td style="width:15%;">start Date</td><td style="width:15%;">end Date</td><td style="width:15%;">in Time</td><td style="width:15%;">Out Time</td><td style="width:15%;">totalhours Office</td><td style="width:20%;">Details</td>
</tr><tr class="row2" align="left">
<td>01/01/2015</td><td>01/01/2015</td><td>00:00</td><td>00:00</td><td>00:00</td><td align="left">Holiday</td>
</tr><tr class="row2" align="left">
<td>01/02/2015</td><td>01/02/2015</td><td>00:00</td><td>00:00</td><td>00:00</td><td align="left">Leave Applied</td>
</tr><tr class="row2" align="left">
<td>01/03/2015</td><td>01/03/2015</td><td>00:00</td><td>00:00</td><td>00:00</td><td align="left">Weekend</td>
</tr><tr class="row2" align="left">
<td>01/04/2015</td><td>01/04/2015</td><td>00:00</td><td>00:00</td><td>00:00</td><td align="left">Weekend</td>
</tr><tr class="row2" align="left">
<td>01/05/2015</td><td>01/05/2015</td><td>13:02</td><td>19:01</td><td>04:38</td><td align="left"> </td>
</tr>
</tbody></table></div>

I have faced similar issue and have resolved by using String.format().
String xpath = "//*[#id='divAttendanceDetails']/table[1]/tbody/tr[%s]/td[%s]";
String cellvaues = driver.findElement(By.xpath(String.format(xpath, getrowvalue, getcolumnvalue))).getText();

one issue with yours xpath is its indexes. Xpath indexes starts with 1.
ref: Why do indexes in XPath start with 1 and not 0?
but this can be issue if you have only one row, results for other rows should be displayed.
It will be helpful if you share the HTML and your current output.

Followed the html you have provided. It does not necessarily matches the code you have in original post.
List<WebElement> Rows = driver.findElements(By.cssSelector("#dgResults tr"));
System.out.println("NoofRowsinthetable" + Rows.size());
for (int i = 0; i < Rows.size(); i++)
{
//find the columns in specific row
List<WebElement> Columns = Rows.get(i).findElements(By.cssSelector("td"));
System.out.println("NoofColumnsinthetable" + Columns.size() );
for (int j = 0; j < Columns.size(); j++ )
{
String text = Columns.get(j).getText();
System.out.println(text);
/* adjust as you needed.
if(identifyvalue.equalsIgnoreCase(text))
{
leavecount = leavecount+1;
System.out.println("Leavecounttilldate" + leavecount );
}
*/
}
}
Note: I didn't test the code on my end. May have some syntax issue

Related

unable to retrieve the Table th tag value using webdriver with java

From the below html i want to check each row in the table header value and if matched need retrieve the td value
below is my html
<table class="span-5" id="summaryTable" title="Table showing Summary data">
<tbody>
<tr>
<th class="width-40" id="num">
(12) App no:
</th>
<td headers="num">
(11)
<strong>2796179</strong>
</td>
</tr>
<tr>
<th class="noLines alignLeft width35" id="EnglishTitle">
(54) English Title:
</th>
<td class="noLines alignLeft width65" headers="EnglishTitle">
FRAME BIT-SIZE ALLOCATION
</td>
</tr>
<tr>
</tbody>
</table>
i want to collect the each th tag value (i.e (12) App no (54) English Title)
my java code
WebElement summary = driver.findElement(By.xpath("//*[#id='summaryTable']/tbody"));
List<WebElement>rows = summary.findElements(By.tagName("tr"));
for (int i=1;i<=rows.size();i++){
String dc = driver.findElement(By.xpath("//*[#id='summaryTable']/tbody/tr["+i+"]/td/th/a")).getText();
if (dc.equalsIgnoreCase("(12) App no")){
appNo = driver.findElement(By.xpath("//*[#id='summaryTable']/tbody/tr["+i+"]/td/strong")).getText();
}
}
but i'm getting no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id='summaryTable']/tbody/tr[1]/td/th/a"}
Please use the below code for this
WebElement elem = driver.findElement(By.id("summaryTable"));
List<WebElement> lists = elem.findElements(By.tagName("th"));
for(WebElement el : lists){
WebElement element = el.findElement(By.tagName("a"));
String str = element.getAttribute("innerHTML");
System.out.println(str);
}
I think you are making it a bit complicated, can you try bit simpler version?
public String getRequiredDataFromTableFromRow(String header){
WebElement table = driver.findElement(By.id("summaryTable"));
List<WebElement> rows = table.findElements(By.tagName("tr"));
for (WebElement row:rows) {
if(row.getText().contains(header)){
return row.findElement(By.tagName("td")).getText();
}
}
return null;
}
Cells are also arrays within the row, so you need to specify the position to get the text. The th tag is not there within the td tag.
Try the following code:
WebElement summary = driver.findElement(By.xpath("//*[#id='summaryTable']/tbody"));
List<WebElement>rows = summary.findElements(By.tagName("tr"));
for(int i = 1; i <= rows.size(); i++) {
String dc = driver.findElement(By.xpath("//*[#id='summaryTable']/tbody/tr[" + i + "]/th[0]")).getText();
if(dc.equalsIgnoreCase("(12) App no")) {
appNo = driver.findElement(By.xpath("//*[#id='summaryTable']/tbody/tr[" + i + "]/td[0]")).getText();
}
}
Below is basically for getting you the text for each "th" element.
WebElement summary = driver.findElement(By.id("summaryTable"));
List<WebElement>rows = summary.findElements(By.tagName("th"));
for(WebElement row : rows){
row.getText();
}}
In the above code, I am getting the reference using the "id" and using same object reference in order to get the elements list for "th" tag.
In case you want to perform operation on the text been found can be done using the reference of the row element

How to target specific td in a HTML document with java

I want to target specific td inside a tr.
This is my code:
private void fletch(String name) throws IOException, JSONException {
final String iron = "img=2";
final String ui = "img=3";
final String hc = "img=10";
String url = "services.runescape.com/m=hiscore_oldschool/hiscorepersonal.ws?user1=";
if ( name.toLowerCase().indexOf(iron.toLowerCase()) != -1 ) {
url = "http://services.runescape.com/m=hiscore_oldschool_ironman/hiscorepersonal.ws?user1=";
}else if( name.toLowerCase().indexOf(ui.toLowerCase()) != -1 ){
url = "http://services.runescape.com/m=hiscore_oldschool_ultimate/hiscorepersonal.ws?user1=";
}else if( name.toLowerCase().indexOf(hc.toLowerCase()) != -1 ){
url = "http://services.runescape.com/m=hiscore_oldschool_hardcore_ironman/hiscorepersonal.ws?user1=";
}
String[] parts = name.split(">");
String part2 = parts[1];
String fin = part2.replaceAll("\\s","+");
url+=fin;
Document doc = Jsoup.connect(url)
.data("query", "Java")
.userAgent("Mozilla")
.cookie("auth", "token")
.timeout(3000)
.post();
//core part
Element table1 = doc.select("table").first();
String body = table1.toString();
Document docb = Jsoup.parseBodyFragment(body);
Element bbd = docb.body();
String hhk = bbd.toString();
//This is where i dont know how to target the td data.. Tried this (cant check code so came on here):
String overall = bbd.getElementsByTag("td").get(4).text();
Now this gives me this HTML code:
<table cellpadding="3" cellspacing="0" border=0 style="max-width: 355px;">
<tr><td colspan="5" align="center"><b>Personal scores for big kurwaaa</b></td></tr>
<tr>
<td colspan="2" style="text-align:left;padding-left:24px;"><b>Skill</b></td><td align="right"><b>Rank</b></td><td align="right"><b>Level</b></td><td align="right"><b>XP</b></td>
</tr>
<tr><td width="35"></td><td width="100"></td><td width="75"></td><td width="40"></td><td width="75"></td></tr>
<tr>
<td></td>
<td align="left"><a href="overall.ws?table=0&user=big+kurwaaa">
Overall
</a></td>
<td align="right">7,430</td>
<td align="right">466</td>
<td align="right">6,164,312</td>
</tr>
<tr>
<td align="right"><img class="miniimg" src="http://www.runescape.com/img/rsp777/hiscores/skill_icon_attack1.gif"></td>
<td align="left"><a href="overall.ws?table=1&user=big+kurwaaa">
Attack
</a></td>
<td align="right">14,475</td>
<td align="right">19</td>
<td align="right">4,304</td>
</tr>
I want to target the 3 td with data inside every tr. So for example:
<td align="right">7,430</td>
<td align="right">466</td>
<td align="right">6,164,312</td>
and so on from the "overall" tr to the last. Is there any way to do in a simple way that will give me the option to loop through the data and create a JSON/map?
Ps: new to java
If you want to get all the tr tags inside bbd use getElementsByTag.
It will return Elements, by which you can browse through all the tr tags by index (0 based index).If want to skip first 3 tr tags just start loop from index : 3, and so for td tags
Here is the demo code :
Elements trList = bbd.getElementsByTag("tr");
for (int i = 3; i < trList.size(); i++) {
System.out.println("----------------- TR START -----------------");
Elements tdList = trList.get(i).getElementsByTag("td");
for (int j = 2; j < tdList.size(); j++) {
System.out.println(tdList.get(j));
}
System.out.println("------------------ TR END ------------------");
}
String url = "yourUrl";
Document doc = Jsoup.connect(url).get();
Element table = doc.select("table[class=tableClass]").first();
Iterator<Element> iterator = table.select("td[align=right]").iterator();
iterator.next();//skip first
iterator.next();//skip second
System.out.println(iterator.next().text());

How to loop through table to find a string match in column 1, then select a dropdown on the same row in another column using Selenium WebDriver Java?

On the UI of the application page I'm testing, there is a table like the image above. The 5th column of the table, each row under the header 'Group' has a dropdown. All of the dropdowns have the same ID 'RIDs'.
Inspecting the 'Apple' warehouse element:
<div id="sdiv" …>
<table id="table10987654321" …>
<tbody>
<tr …>
<td …>
<a …>
<span …>
APPLE</span>
</a>
</td>
…
Inspecting the Group dropdown on the same row as 'Apple' warehouse:
<div id="sdiv" …>
<table id="table10987654321" …>
<tbody>
<tr …>
<td …>
<td …>
<td …>
<td …>
<td …>
<span …>
<select id="RIDs" …>…</select>
</span>
…
To locate all the rows in this table, I wrote:
#FindAll(#FindBy(css="div[id='sdiv']>table[id^='table'] tr"))
List<WebElement> tableRows;
To locate the Group dropdown, I wrote:
#FindAll(#FindBy(css="div[id='sdiv']>table[id^='table'] td:nth-child(5) select[id='RIDs']"))
WebElement dropdownGroup;
After using PageFactory.initElements to initialize elements, now I want to iterate through the first column of the table, row by row, to find the warehouse that I'm looking for, in this case, 'BLUEBERRY' warehouse. If warehouse is 'BLUEBERRY', then select a group from the dropdown in the 5th column of the same row as 'BLUEBERRY' warehouse.
public void selectGroup (String string) {
for (WebElement row : tableRows) {
String warehouseCell = row.findElement(By.cssSelector("td:nth-child(1)).getText());
If (warehosueCell.equals("BLUEBERRY")) {
Select group = new Select(this.dropdownGroup);
group.selectByVisibleText(string);
}
Else {
continue;
}
}
}
Then, in a different class, I'm calling the above method:
String string = "NEWGROUP";
GroupPage page = new GroupPage(driver, WAIT_TIMEOUT);
page.selectGroup(string);
When I run this, it selected the dropdown from the 'APPLE' warehouse row, instead of the 'BLUEBERRY' warehouse row.
How can I change the code so that it selects the dropdown on the same row as the warehouse I am looking for?
I thought about using for loop with index, but the size of the table can change, and new warehouses can be added, so I wouldn't know when to end the loop.
Finally solved it.
#FindAll(#FindBy(css="div[id='sdiv']>table[id^='table'] td:nth-child(5) select[id='RIDs']"))
List<WebElement> dropdownGroups;
public void selectGroup (String string) {
int i = 0;
for (WebElement row : tableRows) {
String warehouseCell = row.findElement(By.cssSelector("td:nth-child(1)).getText());
if (warehosueCell.equals("BLUEBERRY")) {
Select group = new Select(this.dropdownGroups.get(i));
group.selectByVisibleText(string);
System.out.println("Group " + group.getFirstSelectedOption().getText() + " is selected.");
}
else {
i++;
continue;
}
}
}

Adding td element to next tr of rowspan td

I have below html,
<!DOCTYPE html>
<html>
<body>
<table border="1">
<tr>
<th>Month</th>
<th>Savings</th>
<th>Savings for holiday!</th>
</tr>
<tr>
<td>January</td>
<td>$100</td>
<td rowspan="2">$50</td>
</tr>
<tr>
<td>February</td>
<td>$80</td>
</tr>
</table>
</body>
</html>
I want to generate below html using jsoup,
<tr>
<th>Month</th>
<th>Savings</th>
<th>Savings for holiday!</th>
</tr>
<tr>
<td>January</td>
<td>$100</td>
<td rowspan="2">$50</td>
</tr>
<tr>
<td>February</td>
<td>$80</td>
<td>$50</td>
</tr>
I have currenty written this piece of code through which i can get the rowspan cell and its associated td index
final Elements rows = table.select("tr");
int rowspanCount=0;
String rowspanString ="";
for(Element row : rows){
int rowspanIndex = 0;
for(Element cell: row.select("td")){
rowspanIndex++;
if(cell.hasAttr("rowspan")){
rowspanCount = Integer.parseInt(cell.attr("rowspan"));
rowspanString = cell.ownText();
cell.removeAttr("rowspan");
}
}
}
Possible HINT: For condition,
cell.hasAttr("rowspan")
Get row-index, like;
int index = row.getIndex();
and then get next Row by index+1, like;
Element eRow = rows.get(index+1);
then append td-Element to this row, this would be your next row to rowspan-row.
After coding everything, I found the solution. Below is the code,
for (Element row : rows) {
int cellIndex = -1;
if(row.select("td").hasAttr("rowspan")){
for (Element cell : row.select("td")) {
cellIndex++;
if (cell.hasAttr("rowspan")) {
rowspanCount = Integer.parseInt(cell.attr("rowspan"));
cell.removeAttr("rowspan");
Element copyRow = row;
for (int i = rowspanCount; i > 1; i--) {
nextRow = copyRow.nextElementSibling();
Element cellCopy = cell.clone();
Element childTd = nextRow.child(cellIndex);
childTd.after(cellCopy);
}
}
}
}
}
It duplicates the rowspan cell to all the following rows that should contain it. As well removes the attribute rowspan for removing any further discrepancy.
You can append this row simply with this code:
Elements rows = table.select("tr > td[rowspan=2]");
for (Element row : rows) {
row.parent().nextElementSibling().append("<td>$50</td>");
}

JSP/Java table issue

I have a table that is populated depending on how many cars are there. If the number of cars is 1 it will give me the 1 row (where 5 attributes are arranged in 5 columns). If the number of cars is 2 it will give me 2 rows(same 5 attributes), & so on. Now I need to split the table into as many cars are there so that there is just one row for every car. I need to do it in JSP and trying to use the tag <c:choose> or <c:if>, but isn't working . Please help
You need <c:forEach> here. With it you can iterate over any List<T> and print the <tr> on every iteration. Assuming that you have populated a List<Car> and put it in the EL scope as ${cars}, here's an example:
<table>
<c:forEach items="${cars}" var="car">
<tr>
<td>${car.make}</td>
<td>${car.model}</td>
<td>${car.type}</td>
<td>${car.color}</td>
<td>${car.price}</td>
</tr>
</c:forEach>
</table>
See also:
Beginning and intermediate JSP/Servlet tutorials
Hidden features of JSP/Servlet
<html>
<head>
<title>Sample code - Traversing an HTML Table with JavaScript and DOM Interfaces</title>
<script>
function start() {
// get the reference for the body
var body = document.getElementsByTagName("body")[0];
// creates a <table> element and a <tbody> element
var tbl = document.createElement("table");
var tblBody = document.createElement("tbody");
// creating all cells
for (var j = 0; j < 2; j++) {
// creates a table row
var row = document.createElement("tr");
for (var i = 0; i < 2; i++) {
// Create a <td> element and a text node, make the text
// node the contents of the <td>, and put the <td> at
// the end of the table row
var cell = document.createElement("td");
var cellText = document.createTextNode("cell is row "+j+", column "+i);
cell.appendChild(cellText);
row.appendChild(cell);
}
// add the row to the end of the table body
tblBody.appendChild(row);
}
// put the <tbody> in the <table>
tbl.appendChild(tblBody);
// appends <table> into <body>
body.appendChild(tbl);
// sets the border attribute of tbl to 2;
tbl.setAttribute("border", "2");
}
</script>
</head>
<body onload="start()">
</body>
</html>

Categories