seleniumxpath

Understanding WebElement.findElement() and XPATH


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 the <div> that is inside the parent. However, it is returning 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 2</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 me NoSuchElementException


Solution

  • 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