Как с помощью WebElement.findElements(By.xpath .. сделать поиск только по дочерним узлам?
Вебдрайвер загружает тяжелую страницу и для оптимизации скорости ищу сразу массив
List els = driver.findElements(By.xpath("parentLocator"));
Успешно находятся более тысячи узлов (назовем их родительскими), каждый из которых содержит около сотни дочерних узелков, которые различаются между собой в пределах одного родителя, но повторяются как шаблонный набор от родителя к родителя. Суть вопроса как заставить els.get(2).findElements(By.xpath("//*[@data-module='childComponent'")); делать поиск только по дочерним элементам, а не по всей странице, возвращая массив в тысячу элементов (по числу родителей). Успешно опробован способ поиска по локатору такого вида
String locator = ".//*[@class='feed h-mod'][" + (ii+1)+
"]//*[@data-module='LikeComponent' and @data-type='RESHARE']//*[@class='widget_count js-count']";
WebElement themeLink = driver.findElement(By.xpath(locator));
Но такой способ требует поиска по всей странице и чем больше индекс ii тем тормознутее он работает. Моя логика мне подсказывает что как то можно заставить els.get(2).findElements(By.xpath( искать только по дочерним элементам
делать поиск только по дочерним элементам, а не по всей странице
Дописать ось работы с потомками.
Хотя из описание не очень понятно, какие элементы родительские а какие дочерние. Какая структура поддерева "родитель-ребенок"?
Евгений Ткаченко: после получения всего списка родителей, я хочу обращаться к уже отдельному элементу каждого родителя и находить нужные мне дочерние элементы, принадлежащие только ему, вместо этого els.get(2).findElements(By.xpath( ищет не только во втором родителе, а по всему документу, что существенно в моем случае затрачивает ресурсы.
Алексей, что значит дописать ось работы с потомками? структура дочерних элементов довольно сложная и не хочется зависеть от изменений в этой структуре. Т.е. я знаю что среди дочерних элементов родителя где-то в глубине дерева есть единственный элемент [@data-module='LikeComponent' and @data-type='RESHARE'] и хочу чтобы только он и находился через els.get(2).findElements(By.xpath("//*[@data-module='LikeComponent' and @data-type='RESHARE']'"));
т.е. если я сделаю els.get(2).findElements(By.xpath("/* (с одним слешом), то поиск будет идти только по дочерним элементам первого уровня. 2 слеша делают поиск по всем уровням не только дочерних элементов но и родительских. Какая то нелогичность, неужели нет способа задать поиск по всем дочерним элементам без поиска по всем родителям?
densaface: Есть, это использовать обратные оси. Только все равно при //* это обход всего элементов документа с тем, что бы на первом шаге получить все дочерние элементы и далее через предикаты их отфильтровать.
Кстати, почему "Но такой способ требует поиска по всей странице"? Записть .// означает поиск всех потомков текущего узла контекста и полный поиск будет если только текущий узел это корень. Что из приведенного кода совсем не следует.
Алексей Сундуков: аа, я ступил. Вот что значит эта точка перед слешами)) Все вопрос решен. Спасибо что не отказали в помощи. С точкой поиск проходит только по дочерним элементам. Теперь все быстро работает.