Kan någon snälla hjälpa mig hur man använder innehåller i min xpath? Min xpath ändras hela tiden när användare läggs till, så jag kan inte hitta element med xpath.
Detta är min xpath:
.//*[@id="contentText"]/table/tbody/tr[2]/td/table/tbody/tr/td[1]/table/tbody/tr[9]/td/table/tbody/tr/td[1]/strong[2]
Ändringar när ny användare har lagts till:
.//*[@id="contentText"]/table/tbody/tr[2]/td/table/tbody/tr/td[1]/table/tbody/tr[10]/td/table/tbody/tr/td[1]/strong[2]
Snälla hjälp mig hur jag gör det.
Kommentarer
- Dela HTML och element som du försöker hitta.
Svara
Jag har testat ett ExtJS-program. De flesta sidelementattributen är dynamiska. De ändras inte bara när du lägger till en ny användare eller något, de ändras varje gång du öppnar programmet.
Jag har hittat xpath-uttrycken som jag får från verktygen (Firebug etc.) är inte särskilt användbara. Här är varför:
- svårläst
- bryta lätt
- svårt att felsöka
Vad jag gör istället är att ägna tid åt att titta på HTML och identifiera möjliga unika attribut som inte är dynamiska och kommer med mina egna uttryck. attribut är stati c för ett visst element, använd något annat element på sidan som har statiska attribut med föräldrar / barn / syskonförhållanden att hitta.
Jag använder ofta ”innehåller”, men det finns fler. Här är några exempel:
- flera villkor:
//div[@class="bubble-title" and contains(text(), "Cover")]
- partiell matchning:
//span[contains(text(), "Assign Rate")]
- börjar med:
//input[starts-with(@id,"reportcombo")]
- värde har mellanslag:
//div[./div/div[normalize-space(.)="More Actions..."]]
- syskon:
//td[.="LoadType"]/following-sibling::td[1]/select"
- mer komplex:
//td[contains(normalize-space(@class), "actualcell sajcell-row-lines saj-special x-grid-row-collapsed")]
Ta en titt på sidan W3C XSL-funktioner för att få fler idéer.
Redigera: Länk uppdaterad. Redigera 2: XPATH har ändrats
Kommentarer
- Bra exempel! Jag ’ använder liknande metoder för att automatisera en JSF-app med många dynamiska former. Jag ’ har hittat W3C-specifikationen mycket användbar .
- Vilket nöje att veta att någon där ute har gått samma väg! Tack!
- Den tidigare W3C-specifikationslänken fungerar inte nu. Se denna sida istället.
Svar
Du borde dela upp xpath för att hämta enskilda tabeller för tydlighetens skull.
Jag föreslår följande:
// Get the content or container WebElement content = driver.findElement(By.id("contentText")); //Get the table of users WebElement tblUsers = content.findElement(By.xpath(".//table/tbody/tr[2]/td/table/tbody/tr/td[1]/table")); // Get the rows which change always as and when users are added WebElement allUsers = tblUsers.findElements(By.xpath(".//tbody/tr")); // Loop through each row of users table for(WebElement user : allUsers) { // Get the username WebElement username = user.findElement(By.xpath(".//td/table/tbody/tr/td[1]/strong[2]")); System.out.println("Username: " + username.getText()); }
Kommentarer
- det här ’ t ger verkligen några exempel på hur man använder
contains
Svar
Vi kan använda något som
By.xpath("//td[contains(text(),"youruser")]") //here user text is case sensitive
By.xpath("//td[contains(lower-case(text()),"youruser")]") //to handle case sensitivity. Here user is not case sensitive
Svar
.//*[@id="contentText"]/table/tbody/tr[2]/td/table/tbody/tr/td[1]/table/tbody/tr[10]/td/table/tbody/tr/td[1]/strong[2]
Att XPath bör förkortas drastiskt. Det kommer sannolikt att misslyckas om du testar i olika webbläsare och om något ändras på sidan kan det kasta ett falskt positivt på grund av att det tittar på fel element. Jag rekommenderar att du letar upp ”Relativa XPaths” och även ”XPath Axes”, men jag skulle kunna visa en bättre XPath för dig om du publicerade en skärmdump av HTML och webbsidan.
Baserat på vad du publicerade, du kan göra något som: //table[@id ="something"
eller @class="Something that identifies this specific table"]//tr[contains(text(), "something to identify the row")
eller ./text() = "Exact Text Match"]//strong[2]
Vanligtvis med tabellrader identifierar jag raden baserat på texten från en cell inom raden. //table[@id ="something"
eller @class="Something that identifies this specific table"]//tr[.//td[contains(text(), "something to identify the row")
eller ./text() = "Exact Text Match"]]//td//strong[2][contains(text(), "Partial Text Match")
eller ./text() = "Exact Text Match"]
Svar
Försök med koden nedan:
public List<WebElement> getText(String xpath) throws Exception { return driver.findElements(By.xpath(xpath)).getText(); } if(tool.getText("//\*[@id="contentText"]//\*/table//\*/strong").contains("<yourtext>")) { system.out.println("Your text is available in the particular xpath"); } else { system.out.println("Your text is not available in the particular xpath"); }
Det fungerar bra för mig. Jag kan hitta vilken text som helst på vilken xpath som helst med ovanstående kod.
Svar
2 av din XPath ändras från tr[9]
till tr[10]
. Det verkar som att numret på den tredje ”tr” betyder användarnummer.
I min praxis kan radera det numret extrahera alla användares ”data från HTML. (testad av RSelenium + rvest):
.//*[@id="contentText"]/table/tbody/tr[2]/td/table/tbody/tr/td[1]/table/tbody/tr/td/table/tbody/tr/td[1]/strong[2]
Svar
Även om många svar redan finns kan du även hänvisa till länkarna nedan:
Svar
XPATH
driver.findElement(By.xpath("/html/body/div/input[1]")).sendKeys("123"); driver.findElement(By.xpath("//input[1]")).click(); driver.findElement(By.xpath("(//input[1])[4])")).click(); driver.findElement(By.xpath("//tag[@AN="AV"]")).sendKeys("123"); driver.findElement(By.xpath("//tag[text()="AV"]")).sendKeys("123"); driver.findElement(By.xpath("//tag[@AN="AV" and @AN="AV"]")).click(); driver.findElement(By.xpath("//tag[contains(text(),"usrn")]").getText(); driver.findElement(By.xpath("//tag[contains(@AN,"usrn")]").getText(); driver.findElement(By.xpath("//tag[starts-with(text(),"usrn")]").getText(); driver.findElement(By.xpath("//tag[starts-with(@AN,"usrn")]").getText(); ex : //input[starts-with(@id,"reportcombo")]