Xpath select following (number) sibling inside anchor help - xpath

Sorry in advance if I don't explain this clearly. I will try my best to clarify what I am trying to do. Without further ado...Suppose you have a series of numbers on a page (separated by only a space) where brackets indicate the current page you are on.
It looks like this on the page:
[1] 2 3
The HTML looks like this:
<tr>
<td>
[<a href='link1.php'>1</a>] <a href='link2.php'>2</a> <a href='link3.php'>3</a>
</td>
</tr>
I am simply trying to select the next page number based on the current. I imagine I need to use some form of following-sibling but all I have come up with is //tr/td/a/following-sibling::a[1], which is obviously incorrect. It selects 2 when on page 1 but not 3 when on page 2 as expected. I would have tried to use a[text()[contains(.,'[')]] to select the current-page but the brackets are outside the anchor as opposed to inside. Eek!?
It would be much appreciated if you could explain the thought process along with your solution instead of just pasting the answer. Looking forward to your help.

The next page after 2, will be found by:
//tr/td/a[.='2']/following-sibling::a[1]
First we select the current page based on its string content //tr/td/a[.='2'], and from there select the first following-sibling.
To do this without knowing the current page, we will instead select the a element following the "]".
//tr/td/text()[']'=normalize-space(.)]/following-sibling::a[1]
And in case that there is no current page, we will default to the first a element.
//tr/td/( text()[']'=normalize-space(.)]/following-sibling::a | a )[1]

Related

How xpath works for tags in tags

I am trying to find out the xpath for first name of the facebook page and I have ended it with the following xpath: "**//div[1]/div[1]/div[1]/div[1]/input[#class='inputtext _58mg _5dba _2ph-']**" which is correct. My question is that, there are total 9 div tags on the page but I got it with the fourth div, I am not getting the reason how it's finding it in fourth div?
Page is Facebook home Page and element to find with xpath is Fist name input box
Please help me to understand how it's finding the element using above xpath
I know there are other ways to find xpath but I want to know the reason how it's finding it
I hope I am providing the complete information for the asked question if not let me know
Well it's because your xpath starts with a //. In literal english, it says find a DIV whose child is a DIV whose child is a DIV whose child is a DIV whose child is your INPUT. In your case, it does find a DIV which has INPUT as described by your xpath.
If you replace that // to single /, it will find the first DIV and then will try finding your input. Which it won't be able to find since .. like you said there are 9 DIVs.
Hope that paints a picture. Let me know if you need more explanation.

how to select the second <p> element using Xpath

I am trying to scrape full reviews from this webpage. (Full reviews - after clicking the 'Read More' button). This I am doing using RSelenium. I am able to select and extract text from the first <p> element, using the code
reviewNodes <- mybrowser$findElements(using = 'xpath', "//p[#id][1]")
which is for less text review.
But not able to extract full text reviews using the code
reviewNodes <- mybrowser$findElements(using = 'xpath', "//p[#id][2]")
or
reviewNodes <- mybrowser$findElements(using = 'xpath', "//p[#itemprop = 'reviewBody']")
It shows blank list elements. I don't know what is wrong. Please help me..
Drop the double slash and try to use the explicit descendant axis:
/descendant::p[#id][2]
(see the note from W3C document on XPath I mentioned in this answer)
As you're dealing with a list, you should first find the list items, e.g. using CSS selector
div.srm
Based on these elements, you can then search on inside the list items, e.g. using CSS selector
p[itemprop='reviewBody']
Of course you can also do it in 1 single expression, but that is not quite as neat imho:
div.srm p[itemprop='reviewBody']
Or in XPath (which I wouldn't recommend):
//div[#class='srm']//p[#itemprop='reviewBody']
If neither of these work for you, then the problem must be somewhere else.

How get AJAX elements which XPATH is varying dynamically

In my application one AJAX filed which is displaying some values
When I tried to find out their XPATH it is varying dynamically
for example :
First time when I tried to find out the path it is giving it as .//*[#id='ix-rt-13']. When I refresh the page it is giving it as .//*[#id='ix-rt-6'].
Actually it is displaying 2 values one with id .//*[#id='ix-rt-13'] and second one with .//*[#id='ix-rt-14']. And when I refresh the page it is giving XPath values as .//*[#id='ix-rt-6'] and .//*[#id='ix-rt-7'].
I want to retrieve the second element text. How to do that ?
<li class="ui-menu-item" role="presentation">
<a id="'ix-rt-15" class="ui-corner-all ui-state-focus" tabindex="-1">Being Powerful</a>
</li>
If I understand the question correctly, you can try this XPath :
(//*[starts-with(#id,'ix-rt-')])[2]
Above XPath will search for all elements with id attribute value starts with 'ix-rt-', then return the 2nd result.
If link text does not change, you shouldn't use xpath rather use link text:
driver.findElement(By.linkText("Being Powerful")).click();
However if you bend upon using xpath you may try following:
driver.findElement(By.xpath("//a[contains(#id,'ix-rt-')]")).click();
But this would select the 1st element containing 'ix-rt-' in its id. So it may not work as desired if there are more than 1 such elements. In that case, if you know the index of element on page, you may use following:
driver.findElement(By.xpath("(//a[contains(#id,'ix-rt-')])[2]")).click();

xpath to select closest table to anchor tag with a name

I am trying to use xpath and having difficult on how to call a table element from below html code.
There will be many tables in the html. The one i am interested is the one closest to anchor tag with given name.
Below html part is just a rough idea of what html syntax i am dealing with.
<body>
.
.
.
.
.
<p>
<font><b><a name="myTable" /></b></font></p>
<p><b></p>
<div><p></p></div>
<table>
:
:
:
</table>
.
.
..
I initially was going back to "P" element by calling get parent from anchor tag and then calling next sibling couple of times i reached table.
I know it is not clever way to do it. one more problem is there can be variable siblings.
So all i know for sure is the table i have to look is the closest one to anchor tag with the name.
Can some one give some ideas?
I tried this:
getByXPath("//a[#name=myTable]/table"); ( it wont work because it goes to anchor tag and looks for table in children of anchor tag. But it is not the case here)
Try
//a[#name='myTable']/following::table[1]

Selenium and xpath: Clicking a checkbox in one table's column, based on text in another?

Basically there is a table with names, edit buttons, and a checkbox at the end column that I want to check on with selenium. But I want to make sure I click on the one I created with selenium and that's where my problems begin.
Using the selenium IDE, the names xpath is
//tr[5]/td[2]
The checkbox is
//tr[5]/td[4]/input
So the text is in column 2 and the box is column 4, and my record would be the 5th one. but I cannot for the life of me get ANY text search to work. Even something basic like
<tr>
<td>storeText</td>
<td>//tr[contains(text(), 'McGowan')]/td[2]</td>
<td>text</td>
</tr>
Even if the text matches identically, it gives me the locator not found error. No matter what combination i use to find xpath by text it has never worked, and ive spent quite a few hours reading every combination out there.
We are using the IDE and the RC in html, so no java or any other exporting.
Thank! (My first post!)
//td[text()='McGowan']/../td/input[#type='checkbox']
Let me know if this works for you!
This might be odd, but the coment below the answer, regarding a random click that let to the answer ---> //tr[contains(., 'text')]/td[3]/a <--- was just randomly verified as exactly what I needed.
Good job guys.

Resources