Understanding WebElement.findElement() and XPATH
Solution 1
There are my 2 comments with your sample code
1 - With your posted HTML, the xpath //a/li[2] is not found (we only have 3 elements with //a/li[1])
2 - Assume that we do have right code, you need to understand the differences between single slash and double slash in Xpath
a/b (single slash): select element that has "tag b" and "stands right after" an element that has "a tag"
E.g.:
<a>
<b>
<d>
<c>
</c>
</d>
</b>
</a>
AND
a//b (double slash): select element that has "tag b" and is n-level-child an element that has "a tag"
E.g.:
<a>
<c>
<d>
<b>
</b>
</d>
</c>
</a>
So, with your code
<a>
<li> parent 1
<div>
<span class="child-title child-style">title 1</span>
<span class="child-date child-style"> date 1</span>
<span class="child-author">author 1</span>
</div>
</li>
</a>
If you want to get Date Info, you should use
WebElement parent = driver.findElement(By.xpath("//a/li"));
WebElement date = parent.findElement(By.xpath("div/span[contains(@class, 'child-date')]"));
WebElement date = parent.findElement(By.xpath("//span[contains(@class, 'child-date')]"));
The code
WebElement date = parent.findElement(By.xpath("span[contains(@class, 'child-date')]"));
Will bring out NoSuchElementException because there is no [span] tag right after [li] tag
Hope help
Solution 2
Try something like:
Use dot(.)
before double slash(//)
It looks for child under the given parent element.
Solution 3
Completely new question ... completely new answer. :(
Try something like:
WebElement parent1 = driver.findElement(By.xpath("//a[1]/li")); // use a[2] for parent2
WebElement author = parent1.findElement(By.xpath("span[@class='child-author']"));
WebElement date = parent1.findElement(By.xpath("span[contains(@class, 'child-date')]"));
WebElement title = parent1.findElement(By.xpath("span[contains(@class, 'child-title')]"));
Solution 4
Try something like :
//a/li[contains(text(), 'parent 1')]/div
It requests for "the <div>
inside a <li>
whose text contains 'parent 1' and who is inside a <a>
.
It might not work if you have more parents because it works with a contains()
(this xpath would also select <li> parent 10 ... </li>
). It would be better if "parent x" were an attribute of the <li>
instead of its text.
derrdji
BY DAY: SDM at Amazon BY NIGHT: Taking care of baby @Deprecated FOR FUN: Battlefield, binge watching shows and movies FOR FUN v2: @See About me.BY NIGHT SOreadytohelp
Updated on July 17, 2022Comments
-
derrdji almost 2 years
I want to use the
WebElement.findElement()
API to locate a node inside the parent node using XPATH//span[@class='child-class']
. I thought this would return me the<div>
that is inside the parent. However, it is returning me the first one it found in the entire DOM tree. Did I use the wrong XPATH?I have also tried using
.//span[@class='child-class']
as the XPATH, but that does return anything.Thank you.
UPDATE:
given the HTML below, I want to define a locator for the child-title
<span>
and child-date<span>
and locate them using WebElement.findElement() API regardless of the parent being "//a/li[1]" or "//a/li[2]"<a> <li> parent 1 <div> <span class="child-title child-style">title 1</span> <span class="child-date child-style"> date 1</span> <span class="child-author">author 1</span> </div> </li> </a> <a> <li> parent 2 <div> <span class="child-title child-style">title 2</span> <span class="child-date child-style"> date 2</span> <span class="child-author">author 3</span> </div> </li> </a> <a> <li> parent 3 <div> <span class="child-title child-style">title 3</span> <span class="child-date child-style"> date 3</span> <span class="child-author">author 3</span> </div> </li> </a>
I have a
WebElement parent2
initialized and located using"//a/li[2]"
,WebElement child = parent2.findElement(By.xpath("//span[@class='child-author']"));
would give me "author 1"WebElement child = parent2.findElement(By.xpath("span[@class='child-author']"));
would give meNoSuchElementException
-
derrdji almost 10 yearsI have tried removing the "//" in my XPATH locator, but that did not work.