问题
I have a structure such as this:
<div class="Container">
<div class="HighlightContainer">
<div class="NodeTextHighlightContainer">
<span class="TreeItemSelected">Products</span>
</div>
<button class="ContainerSelectedMenu" type="button"></button>
</div>
</div>
Because of how the DOM behaves and trying to stay dynamic, I can only target the span that contains text Products. using something like:
Driver.FindElement(By.XPath("//div[contains(@class, 'Container')]/descendant::span[text() = 'Products']"));
However, I need to target the button where class="ContainerSelectedMenu" based of that span element, what is the best approach? Something like getting the parent div of the child of Container then finding the button element.
回答1:
I've found different ways to do this by traversing back up and down which works fine, but my preference now is this approach:
xpath = "//div[contains(@class, 'Container') and descendant::span[text() = 'Products']]//button";
Basically, you put the descendant with text() = 'Products' as part of the requirement for the div tag you really want, which is the parent. Then you can just search for the button easily with a //button, or //button[@class='ContainerSelectedMenu']
You actually don't need the descendant axes here, so it can be simplified a bit with this:
xpath = "//div[contains(@class, 'Container') and .//span[text() = 'Products']]//button";
In English...
- Find a
divthat - 1. has a
@classthat contains "Container" and - 2. has a descendant
spanelement with the text `Products - Find a descendant of that
divthat is abutton
回答2:
One way is to target the span, then go up to the ancestor div, and then back down to the element with the matching class...
//span[normalize-space()='Products']/ancestor::div[contains(@class,'Container')]//*[contains(@class,'ContainerSelectedMenu')]
Another way is to target the div, then the span, then go up the two levels and then back down to the element with the matching class...
//div[contains(@class,'Container')]//span[normalize-space()='Products']/../../*[contains(@class,'ContainerSelectedMenu')]
Yet another way (similar to @mrfreester) is to match the div, test the span, and go directly to the element with the matching class...
//div[contains(@class, 'Container') and .//span[normalize-space()='Products']]//*[contains(@class,'ContainerSelectedMenu')]
All three of these match the button.
来源:https://stackoverflow.com/questions/48531088/xpath-find-parent-of-a-child-element