XPath extract value within attribute - xpath

This is my HTML code so far:
<tr valign="top">
<td nowrap="x">Citation(s)</td>
<td>
<span class="pubmed_id" id="26472973">
26472973
</span>
</td>
</tr>
I would like to extract the number 26472973, which is a value that changes for each entry in the database.

It is unclear if you want to get either the value from the attribute #id or the following a element.
So, for the attribute value, try this XPath:
//tr[#valign='top']/td/span[#class='pubmed_id']/#id
Or, for the element's a value use this XPath:
//tr[#valign='top']/td/span[#class='pubmed_id']/a/text()
In both case the result is 26472973.

In case you just want the 'citations', here another try:
//tr/td[text()='Citation(s)']/following-sibling::td/span/#id

Related

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!

How to get any text between an opening and closing node with xpath?

I want to get the specified text as in example but when I used strong[3] but it returns "Text5:" as expected. How can I get the airport name section with xpath?
Code:
<tr>
<td>
<strong>Text1 </strong>Text2
<strong> Text3: </strong>Text4
<strong>Text5:</strong> Text_Text_Text_Text_Text
</td>
</tr>
The part that I need:
Text_Text_Text_Text_Text
The solution is /tr/td/text()[3]

Xpath: howto return empty values

I have an Xpath like following:
"//<path to some table>/*/td[1]/text()"
and it returns text values of all non-empty tds, for example:
<text1>, <text2>, <text3>
But the problem is that between nodes, that contain mentioned values could be some empty tds elements:
What i want is to get result that contain some identifiers, that there is those empty values, for example:
<text1>,<>, <>, <text2>, <text3>, <>
or
<text1>,<null>, <null>, <text2>, <text3>, <null>
I tried to use next one:
"//<path to some table>/*/string(td[1]/text())"
but it returns undefined
Of course, I could just get whole node and then work with it in my code (cut all unnecessary info), but may be there is a better way?
html example for that case:
<html>
<body>
<table class="tablesorter">
<tbody>
<tr class="tr_class">
<td>text1</td>
<td>{some text}</td>
</tr>
<tr class="tr_class">
<td></td>
<td>{some text}</td>
</tr>
<tr class="tr_class">
<td>text2</td>
<td>{some text}</td>
</tr>
<tr class="tr_class">
<td>text3</td>
<td>{some text}</td>
</tr>
<tr class="tr_class">
<td></td>
<td>{some text}</td>
</tr>
</tbody>
</table>
</body>
</html>
Well simply select the td elements, not its text() child nodes. So with the path changed to //<path to some table>/*/td[1] or maybe //<path to some table>/*/td you will get a node-set of td elements, whether they are empty or not, and you can then access the string contents of each node (with XPath (select string(.) for each element node) or host environment method e.g. textContent in the W3C DOM or text in the MSXML DOM.). That way the empty strings will be included.
In case you use XPath 2.0 or XQuery you can directly select //<path to some table>/*/td/string(.) to have a sequence of string values. But that approach with a function call in the last step is not supported in XPath 1.0, there you can select the td element nodes and then access the string value of each in a separate step.
Do you mean you want only the td[1] with text and get rid of ones without text? If so, you can use this xpath
//td[1][string-length(text()) > 1]

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