XPath - способ выбора элемента на основе частичной строки - PullRequest
0 голосов
/ 07 марта 2012

Если у меня есть несколько гиперссылок на странице, указанной в сетке, и я просто хочу сфокусироваться на первой гиперссылке, есть ли способ получить ссылку на ссылку тега, основанную на части текста href?

пример, скажем, на странице есть несколько гиперссылок с именами машин:

<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>

Итак, я хочу сделать что-то подобное для моего xPath:

"//table[@id='{0}']/a[href{1}]", usersGridId, "/Customers/");

Итак, получите первую гиперссылку с / Customers / в ее href. Я не знаю, можете ли вы просто выполнить частичное совпадение строк ... или, другими словами, регулярное выражение с XPath, не так ли? В этом случае я не хочу зависеть от CustomerId, потому что я не знаю, каким будет этот Id, поскольку сетка динамическая. Все, что меня волнует, это получение ссылки на первую гиперссылку в списке сетки, независимо от того, кто это.

UPDATE:

Забыл добавить, что я использую XPath с веб-фреймворком Selenium.

UPDATE:

Дух, только что понял, что у меня уже есть ссылка на эту таблицу (хотя вы не видите этот код здесь ... извините)

Так что я делаю как grid.FindElement (By.XPath (xPath)); где сетка ссылается уже на элемент таблицы. В этой таблице есть tbody, поэтому я попытаюсь добраться до элемента a вот так:

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));

на этот раз тоже не повезло.

также попробовал следующее на основе обновленного кода выше:

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");

Вот структура страницы, где я пытаюсь перейти по гиперссылке

<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>someDude@gmail.com</td>
            </tr>
        .. next user, and so on
        </tbody>
    </table>
</div>

UPDATE:

попробовал это, не повезло:

string xPath = (string.Format("//tbody[@id={0}]/tr/td/a(starts-with(@href, {1})", usersTableId, " /Customers/"));
OurSeleniumDriverInstance.FindElement(By.XPath(xPath ));

Ответы [ 3 ]

3 голосов
/ 07 марта 2012

Хотя вы можете сделать это с XPath, как показано на yajoe, я бы также предложил использовать LINQ to XML, если вы можете:

var query = doc.Descendants("table")
               .Where(table => (string) table.Attribute("id") == usersGridId)
               .Elements("a")
               .Where(a => a.Attribute("href").Value.StartsWith("/Customers/"));

Я предпочитаю это, так как части «данных» отделяются от частей «кода», очень похоже на параметризованный оператор SQL.

(Конечно, это зависит от того, используете ли вы .NET 3.5 или выше.)

3 голосов
/ 07 марта 2012

Да, xpath и xquery поддерживают совпадение подстрок. Подвох в том, что вам нужно использовать одну из функций, чтобы сделать это. Ваш xpath будет выглядеть следующим образом (ну, ваш C # для генерации xpath ...):

"//table[@id='{0}']/a[starts-with(@href,'{1}')]", usersGridId, "/Customers/");

Все функции определены здесь: http://www.w3schools.com/xpath/xpath_functions.asp

Редактировать: добавлено '@' для обозначения атрибута href. Спасибо за улов.

Редактировать # 2: я не знаю, почему мой ответ не был принят - xpath правильный и работает. Что-то, что бросается в глаза, это то, что вряд ли тег a является потомком тега table . Вам не хватает тегов tr и td между ними?

1 голос
/ 07 марта 2012

Вы можете использовать функцию XPath starts-with:

string.Format("//table[@id='{0}']/a[starts-with(@href,'/Customers/']",
       usersGridId);

ПРИМЕЧАНИЕ Ваш XPath не был правильно структурирован, href является атрибутом, поэтому должен иметь префикс сСимвол @ указывает, что он находится на оси атрибута.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...