Как использовать отрицание селектора (но...) в Enlive для более сложного фрагмента HTML?
У меня есть фрагмент HTML, похожий на:
<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>
Теперь я хотел бы выбрать все фрагменты, имеющие атрибут_2 (* [attrb_2]), за исключением тех, которые являются потомками node, имеющих атрибут_1. В этом примере может быть больше уровней вложенности с произвольными тегами (например, <p>
). С Enlive (http://enlive.cgrand.net/), я уже пробовал что-то вроде:
(select snippet [(but (attr? :attrib_1)) (attr? :attrib_2)])
Но это не работает, потому что отрицание (but (attr? :attrib_1))
соответствует тегу <p>
. Есть ли способ выразить это с помощью заданных предикатов селектора (http://enlive.cgrand.net/syntax.html), или мне нужно написать свой собственный?
Заранее спасибо
-Jochen
Ответы
Ответ 1
Вам нужно написать свой собственный селектор:
(def parents
(zip-pred (fn [loc pred]
(some pred (take-while identity (iterate zip/up loc))))))
(непроверенные)
а затем
(select snippet [[(attr? :attrib_2) (but (parents (attr? :attrib_1))]])
должен работать.
Ответ 2
#root #a attrib_2{}
#root #b attrib_2{}
#root #c attrib_2{}
#root #d attrib_2{}
#root #e attrib_2{}
который выберет все атрибуты attrib2 в css внутри корневого div.
Ответ 3
Просто ради аргумента, не могли бы вы сделать это:
<div id="whatever" class="attrib_2 bar"></div>
Семантически кажется, что это было бы лучше, но опять же я не знаю, какие системы вы используете или какова ваша конечная цель. Однако, если бы вы использовали классы, CSS был бы предельно прост:
div.attrib.bar {
something:else;
}