Variable Reference в xPath

  • Автор темы Автор темы surr
  • Дата начала Дата начала

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 перечитываю уже в который раз, никак не пойму в чём проблема.
 
А если так "/html/body/div/table/tbody/tr["+i+"]/td[1]/div/a"
 
rostonix, да спасибо, так заработало. Только кавычки экранировать не забыть ;)
"/html/body/div/table/tbody/tr[\"+i+\"]/td[1]/div/a"
А что это за конструкция "+i+"? Как гуглить чтобы почитать про неё?
 
просто собираю строку из нескольких частей.
сначала текст + переменная + текст
текст должен быть в кавычках
 
Понятно. Спасибо.
 
Попила крови у меня эта переменная, а всё потому что надо тестировать сразу, а не ждать пока накопится ещё сотня строк кода. Потом в этой каше на порядок сложнее отыскать проблему.

К сути. Напрямую обратиться к переменной внутри 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, или придётся подключать сторонние библиотеки.
К примеру, у нас есть таблица где-то на просторах сети:
[TABLE="class: brtb_item_table"][TBODY][TR][TD]1[/TD][TD]ЦСКА[/TD][TD]10[/TD][TD]24[/TD][/TR]
[TR][TD]2[/TD][TD]Зенит[/TD][TD]9[/TD][TD]23[/TD][/TR]
[TR][TD]3[/TD][TD]Спартак[/TD][TD]10[/TD][TD]23[/TD][/TR]
[TR][TD]4[/TD][TD]Локо [/TD][TD]9 [/TD][TD]22 [/TD][/TR]
[TR][TD]...[/TD][TD]... [/TD][TD]... [/TD][TD]...[/TD][/TR]
[TR][TD]99[/TD][TD]Команда[/TD][TD]Игр[/TD][TD]Очков[/TD][/TR][/TBODY][/TABLE]
Нам нужно забрать значение игр-очков только для определённых команд (например, с 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("Список готов!");

Результирующая таблица будет иметь вид
[TABLE="class: brtb_item_table"][TBODY][TR][TD]значение[/TD][TD]Локо: 9 (22)[/TD][/TR]
[TR][TD]значение[/TD][TD]Торпедо: 9 (21)[/TD][/TR]
[TR][TD]значение[/TD][TD]Динамо: 9 (21)[/TD][/TR]
[TR][TD]значение[/TD][TD]Амкар: 9 (20)[/TD][/TR][/TBODY][/TABLE]
 
другим способом решение так и не нашлось?
 
у меня вот так получилось
Код:
Развернуть Свернуть Копировать
var menu = "//span[text()='"+project.Variables["NameTeam"].Value+"']";
var menu2 = instance.ActivTab.FindElementByXPath(menu,0);
 
еще вот так работает четко

Код:
Развернуть Свернуть Копировать
string count = project.Variables["variable"].Value;
string xpath_exp = "//div[@id='more_images']/img[" + count + "]";
 

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