Wie finde ich mit XPath ein Element nach CSS-Klasse?


297

Auf meiner Webseite gibt es eine divmit einem classNamen Test.

Wie finde ich es mit XPath?



Die allgemeineren verwandten XPath-, CSS-, DOM- und Selenium-Lösungen finden Sie in Dokument XPath, CSS, DOM und Selenium: The Rosetta Stone . Ihre Antwort finden Sie im Artikel ID & Name .
Terence Xie

Antworten:


472

Dieser Selektor sollte funktionieren, ist jedoch effizienter, wenn Sie ihn durch das entsprechende Markup ersetzen:

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

Oder, da wir wissen, dass das gesuchte Element a ist div:

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

Da dies jedoch auch mit Fällen wie class="Testvalue"oder class="newTest"übereinstimmt, ist die in den Kommentaren angegebene Version von @ Tomalak besser :

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

Wenn Sie wirklich sicher sein möchten, dass es korrekt übereinstimmt, können Sie auch die Funktion zum Normalisieren des Leerzeichens verwenden, um streunende Leerzeichen um den Klassennamen zu bereinigen (wie von @Terry erwähnt):

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

Beachten Sie, dass in all diesen Versionen das * am besten durch den Elementnamen ersetzt werden sollte, mit dem Sie tatsächlich übereinstimmen möchten, es sei denn, Sie möchten jedes einzelne Element im Dokument nach der angegebenen Bedingung durchsuchen.


37
@meder: Eher wie //div[contains(concat(' ', @class, ' '), ' Test ')]- Ihre werden auch teilweise Übereinstimmungen auftauchen.
Tomalak

5
Warum machst du nicht einfach // div [@ class = 'Test']
Jessica

11
Weil Klassen mehr als einen Wert enthalten können
meder omuraliev

8
Ich bin überrascht, dass xpath keine Verknüpfung / effizientere Möglichkeit hat, ein Token in einer durch Leerzeichen getrennten Tokenliste zu finden. Gibt es etwas in späteren Versionen von xpath?
Thomasrutter

1
@thomasrutter warum die Überraschung - dies ist nur eine Sprache für XML, nicht das spezifischere HTML, und wer sagt, dass es lässig ist, durch Leerzeichen getrennte Listen als Knotenwert in XML zu verwenden. Tomalaks Lösung ist sehr praktikabel.
Bitoolean

152

Einfachster Weg ..

//div[@class="Test"]

Angenommen, Sie möchten <div class="Test">wie beschrieben finden.


3
Die obige Syntax ist viel einfacher zu verwenden und weniger fehleranfällig. Denken Sie daran, dass Sie die DOPPELZITATE um die Klasse haben müssen, um suchen zu können. Ich würde empfehlen, die oben aufgeführten zu verwenden. // div [@ class = "Test"]
FlyingV

Funktioniert dies für die Fälle, in denen div [class = 'Test'] auf einer tieferen Ebene liegt?
Jake0x32

1
@ Jake0x32, das liegt daran, dass es //nicht nur verwendet /.
Solomon Ucko

7
Entspricht es auch `<div class =" Test some-other-class ">?
Jugal Thakkar

11
@JugalThakkar Nein, das tut es nicht. Es erfordert eine genaue Übereinstimmung, um zu funktionieren, aber Sie können stattdessen // div [enthält (@class, "Test")] versuchen.
Olli Puljula

29

Der EINZIGE richtige Weg, dies mit XPath zu tun:

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

Die Funktion entfernt normalize-spaceführende und nachfolgende Leerzeichen und ersetzt außerdem Sequenzen von Leerzeichen durch ein einzelnes Leerzeichen.


Hinweis

Wenn Sie nicht viele dieser Xpath-Abfragen benötigen, können Sie eine Bibliothek verwenden, die CSS-Selektoren in XPath konvertiert, da CSS-Selektoren in der Regel viel einfacher zu lesen und zu schreiben sind als XPath-Abfragen. In diesem Fall können Sie beispielsweise beide verwenden div[class~="Test"]und div.Testdas gleiche Ergebnis erzielen.

Einige Bibliotheken, die ich finden konnte:


24

Ich gebe dies nur als Antwort, wie Tomalak es vor langer Zeit als Kommentar zur Antwort von Meder gegeben hat

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

3
Es tut mir leid, dass ich das von vor so langer Zeit angesprochen habe, aber was ist mit concat(' ', normalize-space(@class), ' ')der Berücksichtigung aller möglichen Leerzeichen?
Terry

Aus Neugier - Warum werden //div[contains(concat(' ', @class, ' '), ' Test ')]/chidkeine Kinder ausgewählt?
Fusion

@Fusion Wenn Sie dies als Frage posten, erhalten Sie möglicherweise eine Antwort.
Bitoolean

@bitoolean Captain Cbvious zu sein ist heutzutage schwer
Fusion

@Fusion Ich habe nur versucht zu helfen. XPath ist keine HTML-fähige Sprache. Es ist allgemeiner und nur XML. Ich habe keine Erfahrung damit, aber ich denke, Sie gehen davon aus, dass Sie einfach die ID anstelle des Tags einfügen können. Sie müssen den Wert des Attributs "id" auswählen. Sie müssen sich das HTML-Dokument also als XML vorstellen. Off-Topic-Diskussionen helfen den Leuten jedoch nicht, Lösungen zu finden.
Bitoolean

1

Eine hilfreiche Funktion kann aus früheren Antworten gemacht werden:

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

Dann konzentrieren Sie einfach den Funktionsaufruf in Ihre Abfrage.


Dieser Code würde nur in PHP funktionieren. Du hättest es erwähnen können.
Bitoolean

0

Match gegen eine Klasse mit Leerzeichen.

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

-6

Sie können Elemente wie dieses Beispiel finden (alle CSS-Elemente)

private By 
allElementsCss = By.xpath(".//div[@class]");
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.