Selenium webdriver : exclude child node - java

Here is the sample HTML Code :
<table width="100%" cellspacing="0" cellpadding="0" border="0">
<tbody>
<tr>
<tr class="tinyfont">
<tr height="2px">
<tr height="1px">
<tr height="1px">
<tr>
<tr height="2px">
<tr height="1px">
<tr height="1px">
<tr height="2px">
</tbody>
</table>
I am using selenium webdriver.
I have received the all the child elements from this code but now I want to exclude one particular child element in logic, how I can exclude one of the child element from my array.
I want to exclude tr[6] child element..
List<WebElement> list = driver.findElements(By.xpath("/html/body/table/tbody //*"));
ArrayList<String> al1 = new ArrayList<String>();
for(WebElement ele:list){
String className = ele.getAttribute("class");
System.out.println("Class name = "+className);
al1.add(className);
}
Thanks in Advance!!

Either omit the 6th table row, then select all descendants:
/html/body/table/tbody/tr[position() != 6]//*
or only select all table rows that are not at position 1 and have an attribute (and then select their descendants):
/html/body/table/tbody/tr[position() = 1 or #*]//*
or to be more specific, also check the attribute name:
/html/body/table/tbody/tr[position() = 1 or #height or #class]//*

Is it always element 6 that you want to avoid? If it is, use a for look with an increment and just avoid element 6 with an if statement.
int numOfElements = driver.findElements(By.xpath("/html/body/table/tbody //*")).count();
ArrayList<String> al1 = new ArrayList<String>();
for(int i = 1; i<= numOfElements; i++)
{
if(i!=6)
{
String className = driver.findElement(By.xpath("/html/body/table/tbody/tr["+i+"]")).getAttribute("class");
System.out.println("Class name = "+className);
al1.add(className);
}
}
This wont sound like a solution that you are looking for, but it still is a round about way to achieve what you want. Off the top of my head, I cant think of another way unless you have a attribute that contains something to compare off of or to exclude

Related

How can I get the XPATH directly from accessed element using different selector [duplicate]

I would like to find an element using a differect cssSelector / tag / ClassName amd them get it's xpath value ( to be more specific, I have a website where when a day changes, one of the classes change it's class) here is what do I meean:
<tr>
<td> 1.1.2019 </td>
<td> 2.1.2019 </td>
<td class="active"> 3.1.2019 </td>
<td> 4.1.2019 </td>
</tr>
<tr>
<td> </td>
<td> 10 </td>
<td> </td> #Here
<td> </td>
</tr>
I want to according to where is that "active class", click the table under it. ny idea how to do so ?
short version of what I want :
Find element using cssSelector
Get this element's Xpath <- the problem
click it using edited xpath
I want to GET XPATH OF LOCATED ELEMENT , not to locate it using Xpath
You can find the index by locating all the <td> elements in the first row and check wich one has the index
List<WebElement> columns = driver.findElements(By.xpath("//tr[td[#class='active']]/td")); # just an example, can be any other locator
int index = 0;
for (int i = 0 ; i < columns.getSize() ; i++) {
String attribute = columns.get(i).getAttribute("class")
if (attribute != null && attribute.equals("active")) {
index = i + 1;
}
}

Unable to grab attribute value having a space in attribute name using jsoup java instead getting empty string

I'm new to jsoup and trying to grab the attribute value of "title data-original-title" attribute but getting an empty string. I want the value
Jul-30-2015 03:26:13 PM
<table class="table table-hover">
<thead>
<tr style="border-color: #E1E1E1; border-width: 1px; background-color: #F9F9F9; border-top-style: solid;">
<th>Height</th>
<th>Age</th>
<th>txn</th>
<th>Uncles</th>
<th>Miner</th>
<th>GasUsed</th>
<th>GasLimit</th>
<th>Avg.GasPrice</th>
<th>Reward</th>
</tr>
</thead>
<tbody>
<tr><td></td>
<td>
**<span rel="tooltip" data-placement="bottom" title="" data-original-title="Jul-30-2015 03:26:13 PM">1149 days 18 hrs ago</span>**
</td>
My code is
for (int i = total_pages; i >= 1; i--) {
System.out.println("\nDisplaying blocks on page " + i);
String newString = "https://etherscan.io/blocks?p=" + i;
Document d3 = Jsoup.connect(newString).get();
Elements e = d3.select("table.table-hover > tbody");
Elements r = e.get(0).select("tr");
for (Element cr : r) {
Elements test = d3.select("span");
System.out.println(test.attr("data-original-title"));
}
}
Any help would be appreciated. I modified the attribute value to get data placement value and it is being retrieved correctly. But the data-original-title still returns empty string.
Data attributes are special kind of attributes so accessing them is a bit different but still very easy.
Instead of
System.out.println(test.attr("data-original-title"));
use:
System.out.println(test.first().dataset().get("original-title"));
You can try to see if this works :
d3.select("span[data-original-title]").get(0).attr("data-original-title")
Explanation :
This looks for the first span containing attribute "data-original-title" and gets the value of that attribute.

HREF + TEXT with Jsoup

I've the following HTML Page:
</div><div id="page_content_list01" class="grid_12">
<h2><strong class="floatleft">TEXT1</strong></h2><br>
<table>
<tbody>
<tr>
<th class="no_width">
<p class="floatleft">Attachments:</p>
</th>
<td class="link_azure">
<a target="_blank" href="http://www.example.com">TEXT2</a><br/>
</td>
</tr>
</tbody>
</table><h2><strong class="floatleft">TEXT3</strong></h2><br>
<table>
<tbody>
<tr>
<th class="no_width">
<p class="floatleft">Atachments:</p>
</th>
<td class="link_azure">
<a target="_blank" href="http://www.example2.com">TEXT4</a><br/>
</td>
</tr>
</tbody>
</table><h2><strong class="floatleft">TEXT5</strong></h2><br>
<table>
<tbody>
<tr>
Actually I'm doing:
Elements rows = document.select("div#page_content_list01");
Now I to select "TEXT" and link. I wanna to make clickable link, so I'm using:
for (Element eleme : rows) {
Elements elements = eleme.select("a");
for (Element elem : elementi) {
String url = elem.attr("href");
String title = elem.text();
}
}
and I'm getting:
url = "http://www.example.com";
title = "TEXT2";
and it's ok, but in this way I can't read "TEXT1" and "TEXT3".
Can someone help me please?
I think you need to work on the selecors. First, your primary selector
Elements rows = document.select("div#page_content_list01");
will return with a list of ONE element only, since you actually select the div, not the tables or table rows. I would instead do this to get all relevant info:
Elements tables = document.select("div#page_content_list01>table");
for (Element table : tables){
Element h2 = table.previousElementSibling();
String titleStr = h2.text();
Element a = table.select("a").first();
String linkStr = a.attr("href");
}
Note that the Text in the h2 elements is on the same level as the table, not inside a common div. This is why I use the previous sibling notation. Also note that I wrote this out of my head and it is untested. You should get the idea though.

Jsoup remove specific TR id

I try to remove a "TR" on a table with specific id, where I'm got from
String url = "http://citraslider.blogspot.com/2014/03/table-model.html";
Document doc = Jsoup.connect(url).get();
System.out.println(doc);
And print:
<table id="mt" border="0" cellpadding="2" cellspacing="0" width="100%" class="hbtbl">
<tr id="1"><td class="aa"><div class="bb">11</div><b class="nme pn_std">bua</b>: ask 1 ?</td></tr>
<tr id="2"><td class="a"><div class="b">12</div><b class="nme pn_std">bua</b>: ask 2 ?</td></tr>
<tr id="3"><td class="aa"><div class="bb">13</div><b class="nme pn_std">bua</b>: ask 3 ?</td></tr>
<tr id="-1"><td class="a"><div align="center">[prev]</div></td></tr>
</table>
Here is:
Elements elemen= doc.select("tr");
Elements el = doc.getElementsByAttributeValue("id", "-1");
el.remove(0);
System.out.println(el); // Here its work
for (Element e : elemen) {
System.out.println(e.text()+":"+e.attr("id")); // But at this line still show [prev], tr id="-1" still show
e.getElementsByAttributeValue("id", "-1").remove();
}
So, how i can remove "tr id=-1" on a loop results?
<tr id="-1"><td class="a"><div align="center">[prev]</div></td></tr>
Just change your selector to exclude tr for id = -1
Elements elemen= doc.select("tr").not("tr#-1");
More information on the selector syntax here.
Code becomes,
Elements elemen= doc.select("tr").not("tr#-1");
for (Element e : elemen) {
System.out.println(e.text()+":"+e.attr("id"));
}
Gives,
11bua: ask 1 ?:1
12bua: ask 2 ?:2
13bua: ask 3 ?:3

Locating data in a complex table in Selenium Webdriver

I am currently trying to drill down on a user in a table full of users using Selenium webdriver, I have worked out how to iterate through the table but I'm having trouble actually selecting the person I want.
Here is the HTML (modified with X's due to it not being my data)
<table id="XXXXXXXXX_list" cellspacing="0" cellpadding="0" style=" border:0px black solid;WIDTH:100%;">
<tbody>
<tr cellspacing="0" style="height: 16px;">
<tr>
<tr onclick="widgetListView_onClick('XXXX_list',1,this,event)">
<tr onclick="widgetListView_onClick('XXXX_list',2,this,event)">
<tr onclick="widgetListView_onClick('XXXX_list',3,this,event)">
<tr onclick="widgetListView_onClick('XXXX_list',4,this,event)">
<tr onclick="widgetListView_onClick('XXXX_list',5,this,event)">
<tr onclick="widgetListView_onClick('XXXX_list',6,this,event)">
<tr onclick="widgetListView_onClick('XXXX_list',7,this,event)">
<td class="listView_default_dataStyle" nowrap="" style="font-size:12px ;
font-family: sans-serif ;color: black ;background: #FFFFFF "
ondblclick="XXXXListView_onDblClick('XXXXX_list',17, event)">NAME</td>
<td class="listView_default_dataStyle" nowrap="" style="font-size:12px ;font-family: sans-serif;
color: black ;background: #FFFFFF " ondblclick="XXXXX_onDblClick('XXXX_list',17, event)"> </td>
</tr>
Here is the code I am writing to try and find the user going by NAME in the table.
WebElement table = driver.findElement(By.id("table_list"));
// 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) {
List<WebElement> Names = cell.findElements(By.xpath("//td[text()='NAME']"));
System.out.println(Names);
This just prints thousands of [] (the table is huge in the real application).
Essentially what I need is to stop when I find the correct name and create a web element out of that table row. Which I can then click and drill down on.
Sorry if any of this is a bit vague,
Well if each name in the table is unique, you don't need to complicate things so much. Just search for element with text matching your 'Name' then select the row accordingly. Look at the code below:
WebElement name = driver.findElement(By.xpath("//table[#id='XXXXXXXXX_list']//td[contains(text(),'NAME')]"));//Select td with text NAME in table with id XXXXXXXXX_list
WebElement rowWithName = name.findElement(By.xpath("./.."));//Select the parent node, i.e., tr, of the td with text NAME
/*
* Look into that row for other element or perform any action on the row.
*/
If the names are not unique, i.e., same name exists twice at similar node, 1st instance will be picked each time. In that case we will have to try things differently, i.e., we will have to index the xpath for correct instance of matching name. Do ask if you have any further doubts :)
This will help you out.
try{
ArrayList<WebElement> cells = (ArrayList<WebElement>) driver.findElements(By.tagName("td"));
log4j.info("Value = "+input_type+" is stored in array from Webpage for "+keyword+" ");
for(WebElement type : cells)
{
if(type.getAttribute("name").equals("your correct name here")) {
type.sendKeys("ABC");
}
}
return true;
}catch(Throwable e){
return false;
}
You need to use Array list like this and you can compare your Name in which you wanna fill value Or wanna do any operation like getText(), click() etc.
Enjoy!

Categories

Resources