2011-08-10 64 views
15

我有類似於HTML片段:如何在Enlive中使用選擇符否定(但...)更復雜的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> 

現在,我想選擇具有排除具有attrib_1設置節點的那些是descendands的attrib_2(* [attrb_2])的所有片段。可以有更多的嵌套級別與任意標籤(例如<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

+0

從語義上講,內部'attrib_2'應該是不同的嗎? [編輯:對不起,我在考慮類,它可能實際上有助於識別與屬性不同的範圍。] – Jeremy

+0

此用例是從網頁中提取RDFa元素,如http:// www中所述.w3.org/TR/RDFa的-API /。我想在具有「typeof」屬性的標籤內搜索「屬性」屬性。但只有「直接」的後代。具有「typeof」屬性的後代打開要評估的新上下文。 –

+0

爲什麼你標記這個CSS?我對Enlive並不太熟悉,但如果您試圖在純CSS中實現此解決方案,則可能。 – Wex

回答

4

你必須寫你自己的選擇:

(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))]]) 

應該工作。

+1

如果你只想遍歷父母,你應該在謂詞定義中使用'(iterate zip/up(zip/up loc))'。 –

+0

請注意,zip-pred現在需要一個一元函數,所以'pred'應該作爲'parents'的參數。 –

1
#root #a attrib_2{} 
#root #b attrib_2{} 
#root #c attrib_2{} 
#root #d attrib_2{} 
#root #e attrib_2{} 

,將選擇在根DIV中的CSS所有attrib2片段。

1

爲了討論的緣故,不能你這樣做:

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

語義上好像這將是更好的,但話又說回來,我不知道你使用的是什麼系統,或者你的最終目的是。但是,如果您要使用類,CSS將會非常簡單:

div.attrib.bar { 
    something:else; 
}