it-swarm.com.de

Wie kann ich ein Attribut zuordnen, das eine bestimmte Zeichenfolge enthält?

Ich habe ein Problem beim Auswählen von Knoten nach Attributen, wenn die Attribute mehr als ein Wort enthalten. Zum Beispiel:

<div class="atag btag" />

Dies ist mein xpath Ausdruck:

//*[@class='atag']

Der Ausdruck funktioniert mit

<div class="atag" />

aber nicht für das vorige Beispiel. Wie kann ich den <div> auswählen?

426
crazyrails

Dadurch werden alle unabhängig von der Position der Attribute ausgewählt

//div[contains(@class, 'atag') and contains(@class ,'btag')]
467
surupa123

die Antwort von mjv ist ein guter Anfang, schlägt jedoch fehl, wenn atag nicht der erste aufgeführte Klassenname ist.

Der übliche Ansatz ist der eher unhandliche:

//*[contains(concat(' ', @class, ' '), ' atag ')]

dies funktioniert, solange Klassen nur durch Leerzeichen und nicht durch andere Formen von Leerzeichen getrennt sind. Dies ist fast immer der Fall. Wenn dies nicht der Fall sein sollte, müssen Sie es noch unhandlicher machen:

//*[contains(concat(' ', normalize-space(@class), ' '), ' atag ')]

(Das Auswählen von Zeichenfolgen, die durch Klassennamen wie durch Leerzeichen voneinander getrennt sind, ist ein häufiger Fall. Es ist überraschend, dass es keine spezielle XPath-Funktion dafür gibt, wie CSS3s '[class ~ = "atag"]'.)

297
bobince

EDIT: siehe bobince's lösung die enthält anstatt start-with zusammen mit einem Trick, um sicherzustellen, dass der Vergleich auf der Ebene eines vollständigen Tokens durchgeführt wird (damit das Muster 'atag' nicht als Teil eines anderen 'Tags' gefunden wird).

"atag btag" ist ein ungerader Wert für das Klassenattribut, aber versuchen Sie es trotzdem:

//*[starts-with(@class,"atag")]
38
mjv

versuche dies: //*[contains(@class, 'atag')]

33
SelenUser

Ein 2.0 XPath, der funktioniert:

//*[tokenize(@class,'\s+')='atag']

oder mit einer Variablen:

//*[tokenize(@class,'\s+')=$classname]
30
Daniel Haley

Beachten Sie, dass die Antwort von Bobince möglicherweise zu kompliziert ist, wenn Sie davon ausgehen können, dass der Klassenname, an dem Sie interessiert sind, keine Teilzeichenfolge eines anderen möglichen Klassennamens ist. Wenn dies zutrifft, können Sie einfach den Teilstring-Abgleich über die enthält-Funktion verwenden. Das Folgende stimmt mit jedem Element überein, dessen Klasse die Unterzeichenfolge 'atag' enthält:

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

Wenn die obige Annahme nicht zutrifft, stimmt eine Teilzeichenfolgenübereinstimmung mit Elementen überein, die Sie nicht beabsichtigen. In diesem Fall müssen Sie die Wortgrenzen finden. Durch Verwenden der Leerzeichenbegrenzer, um die Grenzen des Klassennamens zu finden, findet Bobinces zweite Antwort die genauen Übereinstimmungen:

//*[contains(concat(' ', normalize-space(@class), ' '), ' atag ')]

Dies stimmt mit atag und nicht mit matag überein.

20
Brent Atkinson

Um die Antwort von bobince zu ergänzen ... Wenn ein von Ihnen verwendetes Tool/eine Bibliothek Xpath 2.0 verwendet, können Sie dies auch tun:

//*[count(index-of(tokenize(@class, '\s+' ), $classname)) = 1]

count () wird anscheinend benötigt, da index-of () eine Sequenz von jedem Index zurückgibt, bei dem es eine Übereinstimmung in der Zeichenfolge gibt.

7

Sie können Folgendes versuchen

By.CssSelector("div.atag.btag")

4
Umesh Chhabra

Für die Links, die eine gemeinsame URL enthalten, muss eine Variable angegeben werden. Dann versuchen Sie es nacheinander.

webelements allLinks=driver.findelements(By.xpath("//a[contains(@href,'http://122.11.38.214/dl/appdl/application/apk')]"));
int linkCount=allLinks.length();
for(int i=0; <linkCount;i++)
{
    driver.findelement(allLinks[i]).click();
}
0
user3906232