Як я можу знайти елемент за класом CSS з XPath?


296

На моїй веб-сторінці divє classім’я з ім’ям Test.

Як я можу це знайти XPath?



Більш загальні пов'язані рішення XPath, CSS, DOM та Selenium можна знайти в документах XPath, CSS, DOM та Selenium: The Rosetta Stone . Зокрема, вашу відповідь можна знайти в елементі Id & Name .
Теренс Сі

Відповіді:


472

Цей селектор повинен працювати, але буде ефективнішим, якщо замінити його на відповідну розмітку:

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

Або, оскільки ми знаємо, що шуканим елементом є div:

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

Але оскільки це також відповідатиме випадкам на кшталт class="Testvalue"або class="newTest", версія @ Томалака, подана в коментарях, краще :

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

Якщо ви хочете бути впевнені, що він буде відповідати правильно, ви також можете використовувати функцію нормалізації-простір, щоб очистити заблукалі символи пробілів навколо назви класу (як згадує @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?
thomasrutter

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

152

Найпростіший спосіб ..

//div[@class="Test"]

Якщо ви хочете знайти, <div class="Test">як описано.


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

Чи працює це у випадках, коли div [class = 'Test'] лежить на більш глибокому рівні?
Jake0x32

1
@ Jake0x32, це тому, що він використовує //не просто /.
Соломон Учко

7
Чи відповідає воно також <<div class = "Тестувати якогось іншого класу">?
Jugal Thakkar

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

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 бути капітаном Cbvious важко в ці дні
Fusion

@Fusion я просто намагався допомогти. XPath не є інформацією про HTML. Він більш загальний, лише для XML Я не маю жодного досвіду в цьому, але я думаю, ви припускаєте, що можете просто поставити ідентифікатор замість тегу. Потрібно вибрати значення атрибута "id". Тому вам потрібно вважати документ HTML як XML. Дискусії поза темою не допомагають людям знайти рішення.
бітолея

1

Корисну функцію можна зробити з попередніх відповідей:

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

Тоді просто сформулюйте виклик функції у своєму запиті.


Цей код працюватиме лише в PHP. Ви могли це згадати.
Битол

0

Зрівняйтеся з одним класом, який має пробіл.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.