• Clojure, Enlive: how to use negation when using multi-step for selector?

    108 views Asked by At

    I'm using Enlive for Clojure. I'm trying to get span tags with class "title" within li tags, within a specific div tag.

    <div class="main">
        <li><span class="title">wanted</span></li>
        <li><span class="title">wanted</span></li>
        <li class="dummy"><span class="title">NOT wanted</span></li>
    </div>
    

    But, I want to exclude span tags within li tags that have class name "dummy". The code below works as expected:

    (html/select (html/select src [:div.main]) [[:li (html/but 
    :li.dummy)] :span.title])
    

    The question is how to make this work with just one selection call. I wasn't able to use 'but' negation with multiple steps and ended up using nested 2 select calls.

    Can anybody put these into one single select expression?

    1

    There are 1 answers

    1
    glts On

    My guess is that the selector you came up with was exactly the right one.

    The reason why it didn’t match is rather that your HTML is not well-formed – remember that the default TagSoup parser tries to sanitise your input. In your fragment you have list items outside of a list context, and so TagSoup closes the wrapping <div> early.

    You must wrap your list items in a list, for example <ol>:

    <div class="main">
        <ol>
            <li><span class="title">wanted</span></li>
            <li><span class="title">wanted</span></li>
            <li class="dummy"><span class="title">NOT wanted</span></li>
        </ol>
    </div>
    

    Then the following selector should do it:

    (html/select src [:div.main [:li (html/but :.dummy)] :span.title])