Xpath: Select elements based on descendants that do not have a certain attribute

Viewed 62

I am scraping through real estate listings from a certain site that contains multiple pages.

Here, I have summarized a structure nested deep in the DOM. I want to select all list items, based on the descendants that do not have a certain attribute name like <div id="nav-ad-container">

<ul class="photo-cards photo-cards_wow photo-cards_short photo-cards_extra-attribution">
    <li>..</li>
    <li>..</li>
    <li>
        <div id="nav-ad-container" class="zsg-aspect-ratio"></div>
      </li>
    <li>..</li>
    <li>..</li>
    <li>..</li>
</ul>

However, given that the attribute and the attribute's name change in the DOM for each page.

For example:

@id = 'nav-ad-container' or @class = 'nav-ad-empty'

In general, I want to retrieve the list items that do not contain the name pattern 'nav-ad'.

Things that I've tried with no success (still selects every list item)

xpath + //li[not(contains(@class, 'nav-ad'))]
xpath + //li[not((contains(@class,'nav-ad')) or contains(@id,'nav-ad'))]

Can anyone guide me toward a solution? I feel like I'm pretty close but missing something.

2 Answers

filter by classname of list items or descendants:

//li[not(contains(descendant-or-self::node()/@class,'nav-ad'))]

(not tested)

Try

//li[not(descendant-or-self::node()/@class[contains(.,'nav-ad')])]
Related