Variable Reference в xPath

surr

Новичок
Регистрация
09.10.2014
Сообщения
15
Благодарностей
14
Баллы
3
Здравствуйте!
Как правильно обратиться к переменной в xPath?
Вот так возвращает нужное значение:
Код:
string test = tab.FindElementByXPath("/html/body/div/table/tbody/tr[1]/td[1]/div/a", 0).InnerHtml;
return test;
А вот так возвращает пустую строку:
Код:
int i = 1;
string test = tab.FindElementByXPath("/html/body/div/table/tbody/tr[$i]/td[1]/div/a", 0).InnerHtml;
return test;
Спецификацию xPath перечитываю уже в который раз, никак не пойму в чём проблема.
 

rostonix

Известная личность
Регистрация
23.12.2011
Сообщения
29 067
Благодарностей
5 715
Баллы
113
А если так "/html/body/div/table/tbody/tr["+i+"]/td[1]/div/a"
 

surr

Новичок
Регистрация
09.10.2014
Сообщения
15
Благодарностей
14
Баллы
3
rostonix, да спасибо, так заработало. Только кавычки экранировать не забыть ;-)
"/html/body/div/table/tbody/tr[\"+i+\"]/td[1]/div/a"
А что это за конструкция "+i+"? Как гуглить чтобы почитать про неё?
 

rostonix

Известная личность
Регистрация
23.12.2011
Сообщения
29 067
Благодарностей
5 715
Баллы
113
просто собираю строку из нескольких частей.
сначала текст + переменная + текст
текст должен быть в кавычках
 

surr

Новичок
Регистрация
09.10.2014
Сообщения
15
Благодарностей
14
Баллы
3
Понятно. Спасибо.
 

surr

Новичок
Регистрация
09.10.2014
Сообщения
15
Благодарностей
14
Баллы
3
Попила крови у меня эта переменная, а всё потому что надо тестировать сразу, а не ждать пока накопится ещё сотня строк кода. Потом в этой каше на порядок сложнее отыскать проблему.

К сути. Напрямую обратиться к переменной внутри xPath в C# нельзя, хотя согласно спецификации самого xPath такая возможность должна быть ($var).
Код:
int i = 1;
string test = tab.FindElementByXPath("//table/tbody/tr[$i]/td[1]/div/a", 0).InnerHtml;
return test;
При любых значениях i будет выкидывать исключения.

Просто подставить строку в селектор тоже нельзя как оказалось. По непонятным для меня причинам (разбираться лень) селектор всегда примет значение "1".
Код:
int i = 1;
string test01 = tab.FindElementByXPath("//table/tbody/tr[\"+i+\"]/td[1]/div/a", 0).InnerHtml;
string test02 = tab.FindElementByXPath("//table/tbody/tr[\"i\"]/td[1]/div/a", 0).InnerHtml;
string test03 = tab.FindElementByXPath("//table/tbody/tr[1]/td[1]/div/a", 0).InnerHtml;
Во всех трёх примерах xPath будет ссылаться на одну и ту же строку таблицы - первую. В этом для меня была большая подстава, т.к. счётчик начинался именно с единицы, первая итерация выдавала нужное значение, счётчик увеличивался, а значение +i+ оставалось прежним (==1) и поиск продолжался в той же строке.
Т.е.
Код:
int i = 9;
string test01 = tab.FindElementByXPath("//table/tbody/tr[\"+i+\"]/td[1]/div/a", 0).InnerHtml;
i = 13;
string test02 = tab.FindElementByXPath("//table/tbody/tr[\"i\"]/td[1]/div/a", 0).InnerHtml;
string test03 = tab.FindElementByXPath("//table/tbody/tr[1]/td[1]/div/a", 0).InnerHtml;
и в test01, и в test02, и в test03 xPath сошлётся на первую строку таблицы, а никак не на 9-ю или 13-ю.

Обратиться к переменной в xPath в C# можно с помощью метода String.Format, или придётся подключать сторонние библиотеки.
К примеру, у нас есть таблица где-то на просторах сети:
1ЦСКА1024
2Зенит923
3Спартак1023
4Локо 9 22
...... ... ...
99КомандаИгрОчков
[TBODY] [/TBODY]
Нам нужно забрать значение игр-очков только для определённых команд (например, с 4 по 7 места) и записать всё в свою таблицу.
Код:
// Подключаем итоговую excel-таблицу, в которую будем записывать спарсенные значения.
IZennoTable table = project.Tables["resultTable"];

// Заводим счётчики: "a" для парсинга нужных строк в маске xPath, счётчик "i"
// для текущей строки результирующей таблицы.
int i = 0;
int a = 4;
while (a <= 7)
{
    // Делаем приведение для возможности использования значения "a" в методе String.Format.
    string w = a.ToString();

    // Маску xPath создаем с помощью метода String.Format
    // Парсим нужные показатели, объединяем их по маске метода Concat и пишем в нужную ячейку результирующей таблицы.
    string team = tab.FindElementByXPath(String.Format("//table/tbody/tr[{0}]/td[2]/div/a", w), 0).InnerHtml;
    string games = tab.FindElementByXPath(String.Format("//table/tbody/tr[{0}]/td[3]/div/a", w), 0).InnerHtml;
    string scores = tab.FindElementByXPath(String.Format("//table/tbody/tr[{0}]/td[4]/div/a", w), 0).InnerHtml;
    string result = string.Concat(team, ": ", games, " (", scores, ")");
    table.SetCell(1, i, result);

    // Увеличиваем счётчики.
    i++;
    a++;
}
project.SendInfoToLog("Список готов!");
Результирующая таблица будет иметь вид
значениеЛоко: 9 (22)
значениеТорпедо: 9 (21)
значениеДинамо: 9 (21)
значениеАмкар: 9 (20)
[TBODY] [/TBODY]
 

nik-n

Client
Регистрация
05.11.2016
Сообщения
242
Благодарностей
20
Баллы
18
другим способом решение так и не нашлось?
 

Vadim

Client
Регистрация
10.10.2013
Сообщения
48
Благодарностей
7
Баллы
8
у меня вот так получилось
Код:
var menu = "//span[text()='"+project.Variables["NameTeam"].Value+"']";
var menu2 = instance.ActivTab.FindElementByXPath(menu,0);
 

nik-n

Client
Регистрация
05.11.2016
Сообщения
242
Благодарностей
20
Баллы
18
еще вот так работает четко

Код:
string count = project.Variables["variable"].Value;
string xpath_exp = "//div[@id='more_images']/img[" + count + "]";
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)