2

I am trying to look for a node based on text that is available on a child/grandchild node of it's immediate brother. The HTML looks something like this:

<div>
    <div class="searchedDivClass" id="DynamicId1">
    </div>
    <div class="classType1"> 
       //<h1> some text </h1>
    </div>
    //
    <div class="searchedDivClass">
    </div>
    <div class="classType2"> 
         //<p> some other text </p>
    </div>
</div>

As you can see the searched text can be in any type of tag, but it is always part of the text.

I thought that the following XPath would work:

drive.FindElementsByXPath("//div[following-sibling::div[1][//*[contains(text(),'some text')]] and contains(@class,'searchedDivClass')]")

Broken down into pieces:

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

Makes sure it returns the right level of div that I am looking for, not higher up or lower down in the tree.

//div[following-sibling::div[1][//*[contains(text(),'some text')]]

Looks for the first sibling of the div found above. Inside this sibling, it looks for an element that contains the text we are looking for.

However, when I look at how many elements it return, it is actually greater than the number of elements that have the 'searchedDivClass'.

Note that removing the //*[contains(text(),'some text')]

At least returns the number of elements with the searched class.

Finally, that last XPath on it's own correctly returns the element containing the text.

Any idea, or recommendations?

4
  • Which element you want to select actually? Commented Aug 19, 2017 at 5:49
  • I edited my answer to make it a little more clear. I am trying to get the div that has the "DynamicId1", based on the text in a sub-node of it's immediate sibling. Commented Aug 19, 2017 at 5:52
  • Can you update us exactly which element/text are you trying to locate and with respect to which element/text? Commented Aug 19, 2017 at 13:32
  • I was looking for the div with the id: "DynamicId1", based on the text under "h1". The main challenge was that the tag is not always h1, and that we don't know how far down in the "nextSibling" we had to go. Tarun's answer worked out perfectly though. Commented Aug 20, 2017 at 18:10

1 Answer 1

1

So you need to break your problem into two parts

(element we need to select)[condition that element has to match]

Let's solve them one by one

element we need to select

So we know that the element will have a class searchedDivClass. So this one is quite simple and below should work

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

condition that element has to match

The first condition is that that there should be a following div tag (or basically a sibling.

following-sibling::div[1]

Now next condition we want to add on this sibling, which is that this sibling should have a child which has text some text. So we update our xpath with another condition

following-sibling::div[1][.//*[contains(text(),'some text')]]

Notice that i used a .// and not // because .// will take from current nodes child, while the // you use means anywhere in the document.

So our final XPATH will be

//div[@class='searchedDivClass'][following-sibling::div[1][.//*[contains(text(),'some text')]]]
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Tarun, I am currently not next to my laptop, but I'll try it once I have a chance
It looks like what I was missing was the dot in front of the ".//*". This worked out perfectly. Thanks a lot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.