0

I need to match elements with block and result until the first occurrence of the element with class block but NOT result.

XPath:

//div[contains(@class, 'result') and contains(@class ,'block')][following-sibling::div[contains(@class, 'block') and not(contains(@class,
'result'))]]

Example 1 (works in this case):

<div class="block result"></div> <!-- match this -->
<div class="block result"></div> <!-- match this -->
<div class="block"></div>
<div class="block result"></div> <!-- DONT match this -->
<div class="block result"></div> <!-- DONT match this -->

Example 2 (doesn't match anything here)

<div class="block result"></div> <!-- match this -->
<div class="block result"></div> <!-- match this -->

... so it doesn't matching anything in the second example. Can I make the following optional so it matches in both conditions?

eozzy
  • 66,048
  • 104
  • 272
  • 428

2 Answers2

1

Not pretty, but should work...

//div[contains(concat(' ', @class, ' '), ' block ') and contains(concat(' ', @class, ' '), ' result ') and not(preceding-sibling::div[contains(concat(' ', @class, ' '), ' block ') and not(contains(concat(' ', @class, ' '), ' result '))])]

It should match divs with both the block and result classes but only if they don't have a preceding sibling div that contains a block class with no result class.

See answers in this question to see why I'm using concat():

How can I match on an attribute that contains a certain string?

Daniel Haley
  • 51,389
  • 6
  • 69
  • 95
-1

EDIT:

You can put in a List all which contain 'block' and after check with getAttribute("class") if contains "result" until not contain.

List<WebElement> aux = driver.findElements(By.xpath("//div[contains(@class ,'block')]"));

for(WebElement a : aux) {

    if(a.getAttribute("class").contains("result")) {

        System.out.println(a.getText()); //Save in other list


    }else {

        break;

    }

}
KunLun
  • 3,109
  • 3
  • 18
  • 65