15

I have got an HTML snippet similar to:

<div id="root">
    <div id="A" attrib_2="bar"></div>
    <div id="B" attrib_2="baz">
        <div id="H" attrib_1="gnu">
            <p>
                <div id="F" attrib_2="baz"></div>
            </p>
        </div>
    </div>
    <div id="C" attrib_2="owl"></div>
    <div id="D" attrib_2="uhu"></div>
    <div id="E" attrib_2="boom"></div>
</div>

Now, I would like to select all snippets having an attrib_2 (*[attrb_2]) excluding those being descendands of a node having attrib_1 set. There can be more nesting levels with arbitrary tags (like <p> in this example). With Enlive (http://enlive.cgrand.net/), I have already tried something like:

(select snippet [(but (attr? :attrib_1)) (attr? :attrib_2)])

But this doesn't work because the negation (but (attr? :attrib_1)) matches also the <p> tag. Is there a way to express this with the given selector predicates (http://enlive.cgrand.net/syntax.html), or do I have to write my own one?

Thanks in advance

-Jochen

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Jochen Rau
  • 390
  • 1
  • 6
  • Semantically, should the inner `attrib_2` be something different? [Edit: sorry, I was thinking about classes, which might actually be useful to identify the different scopes as opposed to attributes.] – Jeremy Aug 10 '11 at 20:26
  • The use case for this is to extract RDFa elements from a web page as described in http://www.w3.org/TR/rdfa-api/. I want to search for "property" attributes within a tag having a "typeof" attribute. But only the "direct" descendants. An descendant with a "typeof" attribute opens a new context to be evaluated. – Jochen Rau Aug 10 '11 at 21:21
  • Why exactly did you tag this CSS? I'm not too familiar with Enlive, but if you are trying to achieve this solution in pure CSS, it is possible. – Wex Aug 25 '11 at 00:48
  • I tagged this with CSS because Enlive uses the same selector semantics. How do you achieve this in pure CSS? – Jochen Rau Aug 29 '11 at 08:32

3 Answers3

4

You have to write your own selector:

(def parents 
  (zip-pred (fn [loc pred]
              (some pred (take-while identity (iterate zip/up loc))))))

(untested)

and then

(select snippet [[(attr? :attrib_2) (but (parents (attr? :attrib_1))]])

should work.

cgrand
  • 7,939
  • 28
  • 32
1
#root #a attrib_2{}
#root #b attrib_2{}
#root #c attrib_2{}
#root #d attrib_2{}
#root #e attrib_2{}

that will select all attrib2 snippets in css inside the root div.

1

Just for argument sake, couldn't you do this:

<div id="whatever" class="attrib_2 bar"></div>

Semantically it seems like this would be better, but then again I don't know what systems you're using, or what your final purpose is. However, if you were to use classes, the CSS would be extremely simple:

div.attrib.bar {
    something:else;
}
Timothy Miller
  • 2,391
  • 1
  • 27
  • 34