Come posso trovare un elemento per classe CSS con XPath?


297

Nella mia pagina web, c'è un divcon un classnome Test.

Come posso trovarlo con XPath?



Le soluzioni XPath, CSS, DOM e Selenium più generali correlate sono disponibili nel documento XPath, CSS, DOM e Selenium: The Rosetta Stone . In particolare, la risposta può essere trovata nella voce ID e nome .
Terence Xie,

Risposte:


472

Questo selettore dovrebbe funzionare ma sarà più efficiente se lo sostituisci con il markup adatto:

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

Oppure, poiché sappiamo che l'elemento ricercato è un div:

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

Ma poiché questo corrisponderà anche a casi come class="Testvalue"o class="newTest", la versione di @ Tomalak fornita nei commenti è migliore :

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

Se desideri essere davvero certo che corrisponderà correttamente, puoi anche utilizzare la funzione normalize-space per ripulire i caratteri di spazio bianco attorno al nome della classe (come indicato da @Terry):

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

Si noti che in tutte queste versioni, il * dovrebbe essere sostituito con qualsiasi nome di elemento che si desidera effettivamente abbinare, a meno che non si desideri cercare tutti gli elementi nel documento per la condizione data.


37
@meder: Altri simili //div[contains(concat(' ', @class, ' '), ' Test ')]: anche i tuoi genereranno partite parziali.
Tomalak,

5
Perché non fai semplicemente // div [@ class = 'Test']
Jessica l'

11
Perché le classi possono contenere più di un valore
meder omuraliev,

8
Sono sorpreso che xpath non abbia un collegamento / un modo più efficiente per individuare un token in un elenco di token separati da spazio. Qualcosa nelle versioni successive di xpath?
thomasrutter,

1
@thomasrutter perché la sorpresa: questo è solo un linguaggio creato per XML, non l'HTML più specifico, e chi può dire che è casuale usare elenchi separati da spazi come qualsiasi valore di nodo in XML. La soluzione di Tomalak è molto valida.
Bitoolean

152

Il modo più semplice ..

//div[@class="Test"]

Supponendo di voler trovare <div class="Test">come descritto.


3
La sintassi sopra è molto più facile da usare ed è meno soggetta a errori. RICORDA che devi cercare i DOPPI PREVENTIVI nella classe per cercare. Vorrei raccomandare l'uso di quanto sopra elencato. // div [@ class = "Test"]
FlyingV

Questo funziona per i casi in cui div [class = 'Test'] si trova a un livello più profondo?
Jake0x32

1
@ Jake0x32, perché non utilizza //solo /.
Solomon Ucko,

7
Corrisponde anche a `<div class =" Test some-other-class ">?
Jugal Thakkar,

11
@JugalThakkar No, non è così. Per funzionare richiede una corrispondenza esatta, ma puoi provare // div [contiene (@class, "Test")].
Olli Puljula,

29

L' UNICO modo giusto per farlo con XPath:

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

La funzione normalize-spacerimuove gli spazi bianchi iniziali e finali e sostituisce anche le sequenze di caratteri degli spazi bianchi con un singolo spazio.


Nota

Se non hai bisogno di molte di queste query Xpath, potresti voler utilizzare una libreria che converte i selettori CSS in XPath, poiché i selettori CSS sono in genere molto più facili da leggere e scrivere rispetto alle query XPath. Ad esempio, in questo caso, è possibile utilizzare entrambi div[class~="Test"]e div.Testper ottenere lo stesso risultato.

Alcune librerie sono stato in grado di trovare:


24

Sto solo fornendo questo come una risposta, come Tomalak ha fornito come commento alla risposta del mediatore molto tempo fa

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

3
Mi dispiace sollevarlo da tanto tempo fa, ma che ne dici concat(' ', normalize-space(@class), ' ')di tenere conto anche di tutti i tipi di spazi bianchi?
Terry,

Per motivi di curiosità: perché //div[contains(concat(' ', @class, ' '), ' Test ')]/chidnon selezionare i bambini?
Fusion

@Fusion se lo pubblichi come una domanda, potresti ricevere una risposta.
Bitoolean

@bitoolean essendo il Capitano Cbvious è difficile in questi giorni
Fusion

@Fusion Stavo solo cercando di aiutare. XPath non è un linguaggio compatibile con HTML. È più generico, solo XML. Non ho alcuna esperienza al riguardo, ma penso che tu stia assumendo che tu possa semplicemente inserire l'id invece del tag. Devi selezionare il valore dell'attributo "id". Quindi devi pensare al documento HTML come XML. Le discussioni fuori tema non aiutano le persone a trovare soluzioni.
Bitoolean

1

Una funzione utile può essere ricavata dalle risposte precedenti:

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

Quindi concatena la chiamata di funzione nella tua query.


Quel codice funzionerebbe solo in PHP. Avresti potuto menzionarlo.
Bitoolean

0

Abbina una classe con spazi bianchi.

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

-6

puoi trovare elementi come questo esempio (tutti gli elementi CSS)

private By 
allElementsCss = By.xpath(".//div[@class]");
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.