1. 程式人生 > >XPath和CSS 3的解析器比較

XPath和CSS 3的解析器比較

//*[@class='foo' or contains(@class,' foo ') or starts-with(@class,'foo ') or substring(@class,string-length(@class)-3)=' foo']

比起CSS的.foo,真的是好複雜,我來解釋一下,一個元素的class屬性中如果包含'foo',可能有四種情況,列出表來是這樣的:

class="foo" //*[@class='foo'] class屬性只有一個值foo
class="foobar foo bar" //*[@class=' foo '] class屬性值中,foo在其他兩邊的值的中間

class="foo bar"

//*[starts-with(@class,'foo ')] class屬性值中,foo在最左邊
class="bar foo" //*[substring(@class,string-length(@class)-3)=' foo'] class屬性值中,foo在最右邊,XPath1.0中沒有ends-with函式,2.0有,現在瀏覽器實現的都是1.0

那麼我們能在網頁開發中用上XPath嗎?最初,jQuery是支援XPath選擇器的,但後來,由於效率問題,jQuery放棄了對XPath的支援.剛好,谷歌在上個月釋出了Wicked Good XPath,這是一個DOM Level 3 XPath

規範的純JavaScript實現,也是目前同類實現中最快的,我們可以把這個指令碼和jQuery結合起來使用.

jQuery.getScript("http://wicked-good-xpath.googlecode.com/files/wgxpath.install.js").success(function () {    //載入庫檔案
    wgxpath.install();    //安裝XPath支援
    jQuery.xpath = function (xpath) {
        var elements = [];               //用來儲存XPath選擇到的元素
        var
xpathResult = document.evaluate(xpath, document, null, 6, null); for (var i = 0; i < xpathResult.snapshotLength; i++) { elements.push(xpathResult.snapshotItem(i)); } return jQuery(elements); //傳給jQuery工廠方法,返回jQuery物件 } })

這樣就能通過$.xpath()靜態方法來選擇元素了,該方法返回的也是一個jQuery物件,和使用$()沒什麼差別.本頁面已經載入了這個指令碼,你可以現在開啟控制檯試驗一下$.xpath方法.

那我們有了CSS選擇器,為什麼還要用XPath呢,答案是:有些時候,XPath更強大一點.比如:

在上面John Resig總結的表中,有一個CSS無法實現的功能,就是查詢包含某個子元素的父元素.的確,目前的CSS還無法實現,不過在未來CSS4的選擇器中,將會有一個父選擇器

E! > F    //注意,2011年的時候,父選擇器的語法是

該選擇器可以選取到那些包含子元素F的E元素.但即便以後實現了CSS4,稍微改變一下需求,查詢那些包含後代元素F的E元素,CSS選擇器又怎麼寫呢?應該是沒什麼辦法實現.熟悉jQuery的朋友可能會說,jQuery裡有:has偽類,可以這麼寫E:has(F),的確,如果使用jQuery自定義的過濾器,幾乎任何需求都可以用遍歷DOM的方法實現,但效率絕對會很低.而XPath就不一樣了,畢竟Firefox和chrome都已經實現了XPath的介面document.evaluate方法(Wicked Good XPath應該主要是努力在IE上實現統一的介面),速度肯定比手動遍歷DOM來的快.XPath的寫法是這樣的//E[.//F],怎麼樣,也挺簡單明瞭的.

另外很重要的一點是,CSS本來是用於給HTML新增樣式的,12種節點型別中,只有元素節點(nodetype等於1)才有樣式這一說,因此,CSS選擇器只能選取到頁面中的元素節點,而XPath就不是了,它不光可以用在HTML中,還可以用在XML中,除了元素節點,而可以選擇屬性節點(//@*)或者文字節點(//text())等,如果未來XPath2.0實現了,它會變的更加強大.