Reputation: 47733
If I have several hyperlinks on the page listed in a grid, and I just want to get focus to the first hyperlink, is there a way to get ref to an a tag's href based on part of the href text?
example, lets say the page has a bunch of hyperlinks with car names:
<a href="/Customers/7">Adam Backwell</a>
<a href="/Customers/12">Eric Mebratu</a>
<a href="/Customers/5">Dave Johnson</a>
<a href="/Customers/54">Tom Rogan</a>
So I want to do something like this for my xPath:
"//table[@id='{0}']/a[href{1}]", usersGridId, "/Customers/");
So get the first hyperlink with /Customers/ in its href. I don't know if you can do just partial string matches..or in other words regex with XPath can you? In this case I don't want to be dependent on the CustomerId because I don't know what that Id will be as the grid is dynamic. All I care about it grabbing reference to the first hyperlink in the grid list, no matter who it is.
UPDATE:
Forgot to add that I'm using XPath with the Selenium Web framework.
UPDATE:
duh, just realized I already have ref to that table (you don't see that code here though..sorry)
So I'm doing like grid.FindElement(By.XPath(xPath)); where grid references already a table element. Within this table is a tbody so I'm tryign to get to the a element like this now:
IElement gridTable = GetCustomerGrid(); // now represents the table element that holds the customer list
xPath = string.Format("/tbody[@id='{0}']/a[1](contains(@href,'{1}')]", usersGridContainerId, "/Customers");
IWebElement hyperlink = gridTable.FindElement(By.XPath(xPath));
no luck on this one either.
also tried the following based on the updated code above:
string.Format("/tbody[@id='{0}']/a(contains(@href,'{1}')]",usersGridContainerId, "/Customers"); // did not find the hyperlink
string.Format("/tbody[@id='{0}']/a[1](starts-with(@href,'{1}')]",usersGridContainerId, "/Customers"); //invalid XPath Syntax error
string.Format("//tbody[@id='{0}']/a(contains(@href,'{1}')]",usersGridContainerId, "/Customers");
string.Format("//tbody[@id='{0}']/a(starts-with(@href,'{1}')]",usersGridContainerId, "/Customers");
Here's the structure of the page where I'm trying to get at the hyperlink
<div class="table">
<table id="customerList">
<thead>
<tr>
<th class="column1">ID</th>
<th class="column2">Name</th>
<th class="column3">Email</th>
</tr>
</thead>
<tbody id="custListContainer">
<tr>
<td class="column1">7</td>
<td class="column2"><a href="/Customers/7">Joe Smith</a></td>
<td>[email protected]</td>
</tr>
.. next user, and so on
</tbody>
</table>
</div>
UPDATE:
tried this, no luck:
string xPath = (string.Format("//tbody[@id={0}]/tr/td/a(starts-with(@href, {1})", usersTableId, " /Customers/"));
OurSeleniumDriverInstance.FindElement(By.XPath(xPath ));
Upvotes: 0
Views: 7531
Reputation:
Yes, xpath and xquery support matching substrings. The catch is you need to use one of the functions to do it. Your xpath would look like the following (well, your C# to generate xpath...):
"//table[@id='{0}']/a[starts-with(@href,'{1}')]", usersGridId, "/Customers/");
All of the functions are defined here: http://www.w3schools.com/xpath/xpath_functions.asp
Edit: Added the '@' to indicate href is an attribute. Thanks for the catch.
Edit #2: I don't know why my answer was unaccepted -- the xpath is correct and works. Something that sticks out to me is it's unlikely the a tag is a child of the table tag. Are you missing the tr and td tags in between?
Upvotes: 3
Reputation: 1499730
While you can do that with XPath as shown by yajoe, I would also suggest using LINQ to XML if you can:
var query = doc.Descendants("table")
.Where(table => (string) table.Attribute("id") == usersGridId)
.Elements("a")
.Where(a => a.Attribute("href").Value.StartsWith("/Customers/"));
I prefer this as it keeps the "data" parts separate to the "code" parts, much like a parameterized SQL statement.
(Of course, it does rely on you using .NET 3.5 or higher.)
Upvotes: 3
Reputation: 70122
You can use the XPath starts-with
function:
string.Format("//table[@id='{0}']/a[starts-with(@href,'/Customers/']",
usersGridId);
NOTE Your XPath was not structured correctly, href
is an attribute, so needs to be prefixed with the @
symbol to indicate that it is on the attribute axis.
Upvotes: 1