Retrieving text from an element with children - xpath

I am trying to get the text "Weeeeee" but when i use //td[#class='something']/text() I got nothing
<td class="something">
<a href='http://www.google.com'>Google</a>
Weeeeee
<div>
<a>something</a>
</div>
</td>

Try
//td[#class='something']/text()[normalize-space() != ''][1]
as there are three text nodes in your example, the first and the last one consist of whitespace only.
Highlighted with square brackets:
<td class="something">[\n
----]<a href='http://www.google.com'>Google</a>[\n
----Weeeeee\n
----]<div>
<a>something</a>
</div>[\n
]</td>

Related

How Can I get text of all child nodes

I want to get the text of a tag and span tag at the same time.
<td class="desc_autoHeight">
<a rel="nofollow" href="#" target="_blank">Silicon Power</a>
<br><span class="FreeGift">48 Hours Only</span>
</td>
<td class="desc_autoHeight">
<a rel="nofollow" href="#" target="_blank">Silicon Power</a>
48 Hours Only
</td>
Result should be Silicon Power 48 Hours Only
Here is the xpath with concat
concat(//td[#class='desc_autoHeight']/a/text(), ' ', //td[#class='desc_autoHeight']//span[#class='FreeGift']/text())
Screenshot:
If $td is the td element in question, then normalize-space($td) gives you the string you are looking for, at least in this particular example.
In many cases simply using the string value of the element (which you can get using string(), but in many cases that's implicit) is adequate. The difference with normalize-space() is that it turns chunks of spaces and newlines (like the whitespace before the <a> start tag) into a single space, or eliminates it at the start and end.

How to write XPATH in nested elements of siblings

I have such DOM structure:
<td>
<div class="name">Max</div>
</td>
<td>Sales Officer</td>
<td>mail#mail.com</td>
<td class="links">
<a class="edit" href="/edit"><i class="second"></i>Edit Profile</a>
</td>
The main goal is to click on Edit button for particular user. And I have different users (they are in another rows of table).
I need to get xpath which contains the combination of name Max and text Edit Profile.
The main problem for me that both elements are in sibling td tags.
I've never written anything similar before.
//a[text()='Max'] //i[text()='Edit Profile']
What should I add between this to xpathes?
This one should do the trick:
//td[a="Max"]/following-sibling::td/a[.="Edit Profile"]

Find an element by text, get xpath and put in a list as every td is a unique element - selenium webdriver junit

I have a dynamically generated table with thead and tbody. Here is the example:
<tbody id="tableId" class="someclass1">
<tr id="rowId1" class="somesubclass">
<td id="item1" class="othersubclass">
<span class="attr">john Doe</span>
<td id="item2">
<span class="attr">55</span>
<td id="item3">
<span class="attr">5 street</span>
<td id="item2">
<span class="attr">cat</span>
<tr id="rowId2" class="somesubclass2">
<td id="item1" class="othersubclass2">
<span class="attr">joe smith</span>
<td id="item2">
<span class="attr">60</span>
<td id="item3">
<span class="attr">2 street</span>
<td id="item2">
<span class="attr">dog</span>
|joe doe|55|5 street|cat|
|joe foo|60|1 street|dog|
I would like to locate a row by text where the name is joe doe and put it into a list.
Locatior is working with this, but it is not a list.
#FindBy(xpath = "//tbody[contains(#id,'tableId')]/tr[td//text()[contains(.,'joe doe')]]")
private List<WebElement> list;
I got the list, but I cannot iterate over because everything has put into the first position like this:
list first element is: joe doe 55 5 street cat so this is the [0] element
How can I locate this row as a list where every td is a unique element in the list.
(iterate over, converting to string etc. is not a problem, just the locator.)
Thanks!
I don't understand what's for the -1. Anyway, here is the answer for others, hope this helps!
There is a good plugin for google kinda firepath: SelAssist, I use it to test my xpath locators.
The problem was that, td was missing. So the proper locator is
//tbody[contains(#id,'tableId')]/tr[td//text()[contains(.,'joe doe')]]/td
and it gives me list of elements, not only one.
Cheers!

XPath to select specific text inside of text block

I am trying to figure out a way to pull specific values out of a big long text block.
So far I have //td[#class="PadLeft10"] which returns me a big long value starting with the company name and ending with the "View More Info" piece.
I am trying to break my results up into segments, so for example I want my code to look for the words "Primary Contact:" and then return the text that follows that, ending at the <br/>.
I need to get the Company Name, which is always the first bit of text, then the Primary Contact, then the Address, then the Phone and Fax, then the Website, and the Organization type.
The problem is that not every record has all the values. As you can see, the second entry has the address and website, but the first one doesn't.
I am using the Dataminer Chrome Plugin, for anyone familiar with that. It has separate xpath for rows and columns, so I am going to try to make a bunch of different columns that correspond to each of the fields that I am looking for.
Any direction would be greatly appreciated.
<td align="left" valign="top" width="2%">
<script>
if (0 == 1) document.write('<img src="https://website.com" border="0" alt=""/>');
</script>
<br/><br/></td>
<td class="PadLeft10" align="left" valign="top" width="32%" style="padding-left: 15px;">
<span style="font-weight: bold;font-size: 12pt;"><br/>Company Name Here</span><br/>Primary Contact: Mr. Eric Cartman <br/>Phone: (555) 555-5555<br/>Fax: (333) 333-3333<span style="text-decoration: underline;color: #0000ff"></span><br/>Organization Type: Distributor Branch
<br/>
» View More Info<br/>
<br/>
</td>
<td align="left" valign="top" width="2%">
<script>
if (0 == 1) document.write('<img src="https://website.com" border="0" alt=""/>');
</script>
<br/><br/></td>
<td class="PadLeft10" align="left" valign="top" width="32%" style="padding-left: 15px;">
<span style="font-weight: bold;font-size: 12pt;"><br/>Other Company</span><br/>Primary Contact: Mr. Jimmy Valmer<br/>100 N Ohio St 2rd Fl<br/>Rochester, IN 54225<br/>United States<br/>Phone: (888) 888-8888<br/>Fax: (999) 999-9999<span style="text-decoration: underline;color: #0000ff"><br/>Web Site: http://www.companywebsite.com</span><br/>Organization Type: Financial Service
<br/>
» View More Info<br/>
<br/>
</td>
</tr>
<tr>
I am new to xpath, but the least i can say: if you are the creator of the html code, you absolutely need to change it to be more structured
like : Primary Contact:<span id/class='primaryContact'>..</span>
Or else, you can get the elements by this selector (to edit) //td[#class="PadLeft10"]//child::span//following-sibling::text()[1] split by ':' and then proceed, but this solution stay just a diy.
Any direction would be greatly appreciated.
As far as a direction, the sections within table cell that you mention are neither nested DOM items, nor sibling-type DOM nodes. Those are sequential html elements that require special processing.
<br/>Company Name Here</span>
<br/>Primary Contact: Mr. Eric Cartman
<br/>Phone: (555) 555-5555
<br/>...
Both xpath and regex can be leveraged for such a case.
You can select the text node you're looking for using a predicate and the contains function:
//td[#class="PadLeft10"]/text()[contains(., "Primary Contact:")]
Then you can get the substring using the substring-after function:
substring-after(
//td[#class="PadLeft10"]/text()[contains(., "Primary Contact:")],
'Primary Contact:'
)
And remove leading and trailing whitespace using normalize-space:
normalize-space(
substring-after(
//td[#class="PadLeft10"]/text()[contains(., "Primary Contact:")],
'Primary Contact:'
)
)

How do I find if there's a second element exists with the same name with selenium using XPath?

I already know the Text of an element in the table:
string title1 = Driver.FindElement(
By.XPath(
".//[#id='ctl00_ContentPlaceHolder1_BreakdownGridView_ctl02_TitleLabel']"
)).Text;
How do I verify if there's a second element in the table that has the same text as title1?
Here is my Table structure:
<tr class="alt" style="background-color:White;height:110px;">
<td>
<span id="ctl00_ContentPlaceHolder1_BreakdownGridView_ctl03_WindowStartLabel" tabindex="1">
01/13/2013
</span>
</td>
<td>
<span id="ctl00_ContentPlaceHolder1_BreakdownGridView_ctl03_ShowLabel" tabindex="1">
Lea‌​der of the Pack
</span>
</td>
<td>
<span id="ctl00_ContentPlaceHolder1_BreakdownGridView_ctl03_TitleLabel">
Love at First Bite
</span>
</td>
<td>
<span id="ctl00_ContentPlaceHolder1_BreakdownGridView_ctl03_PremiereLabel">
01/12/2013 22:00
</span>
</td>
...
</tr>
After getting title1 try implement logic something like below to find how many elements are there with the same text
int count=driver.findElements(By.xpath("//table[#id='urTable']//*[text()='"+title1+"']")).size();
Based on the count it is easy to find how many elements are there with same text.
In your table structure, doing an xpath query as below would select all the span tags.
//tr/td/span
Now, xpath can be used to select the span tags with specific text as follows:
//tr/td/span[text() = "Text you're matching against"]
/* in your case*/
//tr/td/span[text() = title1]
This is to get spans consist that text....(partial match)
int count= driver.FindElements(
By.XPath(
".//span[contains(text(),'"+titleOneText+"')]"
)).size();
This is to get spans text is same....(full match)
int count= driver.FindElements(
By.XPath(
".//span[text()='"+titleOneText+"']"
)).size();
Based on your question if same xpath value having 2 elements. Just see the static value of particular element and take as xpath. it will work definitely. for example
save & cancel button having same xpath value
driver.find_element_by_xpath("//*[#id='id_sav']")-save
driver.find_element_by_xpath("//*[#id='id_sav']")-cancel
here we can use static element value
driver.find_element_by_xpath("//a[text()='save']")-save
driver.find_element_by_xpath("//a[text()='cancel']")-cancel

Resources