Как я могу найти элемент по классу CSS с XPath?


297

В моей странице, есть divс classименем Test.

Как я могу найти это с XPath?



Более общие решения XPath, CSS, DOM и Selenium можно найти в документе XPath, CSS, DOM и Selenium: The Rosetta Stone . В частности, ваш ответ можно найти в пункте Id & Name .
Теренс Се

Ответы:


473

Этот селектор должен работать, но будет более эффективным, если вы замените его подходящей разметкой:

//*[contains(@class, 'Test')]

Или, поскольку мы знаем, что искомый элемент является div:

//div[contains(@class, 'Test')]

Но так как это также будет соответствовать случаям, подобным class="Testvalue"или class="newTest", версия @ Tomalak, предоставленная в комментариях, лучше :

//div[contains(concat(' ', @class, ' '), ' Test ')]

Если вы хотите быть действительно уверены, что оно будет соответствовать правильно, вы также можете использовать функцию normalize-space для очистки случайных пробельных символов вокруг имени класса (как упомянуто @Terry):

//div[contains(concat(' ', normalize-space(@class), ' '), ' Test ')]

Обратите внимание, что во всех этих версиях * лучше всего заменить на любое имя элемента, которому вы действительно хотите соответствовать, если только вы не хотите искать каждый элемент в документе для заданного условия.


37
@meder: Больше похоже //div[contains(concat(' ', @class, ' '), ' Test ')]- у вас тоже будут частичные совпадения.
Томалак

5
Почему бы вам просто не сделать // div [@ class = 'Test']
Джессика

11
Потому что классы могут содержать более одного значения
meder omuraliev

8
Я удивлен, что у xpath нет быстрого / более эффективного способа найти токен в списке разделенных пробелами токенов. Что-нибудь в более поздних версиях xpath?
Томасруттер

1
@thomasrutter почему сюрприз - это всего лишь язык, созданный для XML, а не более конкретный HTML, и кто скажет, что использование разделенных пробелами списков в качестве любого значения узла в XML непривычно. Решение Томалака очень жизнеспособное.
bitoolean

152

Самый простой способ ..

//div[@class="Test"]

Предполагая, что вы хотите найти, <div class="Test">как описано.


3
Приведенный выше синтаксис намного проще в использовании и менее подвержен ошибкам. ПОМНИТЕ, что вам нужно иметь ДВОЙНЫЕ ЦИТАТЫ вокруг класса для поиска. Я бы порекомендовал использовать перечисленные выше. // div [@ class = "Test"]
FlyingV

Работает ли это для случаев, когда div [class = 'Test'] находится на более глубоком уровне?
Jake0x32

1
@ Jake0x32, это потому, что он использует //не только /.
Соломон Уко

7
Это также соответствует `<div class =" Test some-other-class ">?
Джугал Тхаккар

11
@JugalThakkar Нет, это не так. Для работы требуется точное совпадение, но вместо этого вы можете попробовать // div [Содержит (@class, "Test")].
Олли Пулюла

29

Только правильный способ сделать это с помощью XPath:

//div[contains(concat(" ", normalize-space(@class), " "), " Test ")]

Функция normalize-spaceудаляет начальные и конечные пробелы, а также заменяет последовательности пробельных символов одним пробелом.


Заметка

Если вам не нужны многие из этих запросов Xpath, вы можете использовать библиотеку, которая преобразует селекторы CSS в XPath, поскольку селекторы CSS обычно намного проще читать и писать, чем запросы XPath. Например, в этом случае вы можете использовать оба div[class~="Test"]и div.Testполучить одинаковый результат.

Некоторые библиотеки, которые мне удалось найти:


24

Я просто представляю это как ответ, как Томалак давал в качестве комментария к ответу медика давным-давно

//div[contains(concat(' ', @class, ' '), ' Test ')]

3
Извините, что поднял этот вопрос с того времени, но как насчет concat(' ', normalize-space(@class), ' ')учета всевозможных пробелов?
Терри

Ради любопытства - почему //div[contains(concat(' ', @class, ' '), ' Test ')]/chidне выбирают детей?
Fusion,

@Fusion, если вы разместите это как вопрос, вы можете получить ответ.
bitoolean

@bitoolean быть капитаном Cbvious трудно в эти дни
Fusion

@ Фьюжн Я просто пытался помочь. XPath не является языком, поддерживающим HTML. Это более общий, только для XML. У меня нет никакого опыта в этом, но я думаю, вы предполагаете, что можете просто поставить идентификатор вместо тега. Вам нужно выбрать значение атрибута "id". Поэтому вам нужно думать о HTML-документе как о XML. Вне темы обсуждения не помогают людям найти решения, хотя.
bitoolean

1

Полезная функция может быть сделана из предыдущих ответов:

function matchClass($className) {
    return "[contains(concat(' ', normalize-space(@class), ' '), ' $className ')]";
}

Затем просто включите вызов функции в ваш запрос.


Этот код будет работать только на PHP. Вы могли бы упомянуть об этом.
bitoolean

0

Матч против одного класса, который имеет пробел.

<div class="hello "></div>
//div[normalize-space(@class)="hello"]

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.