2013-11-25 74 views
1

我找不到例子並不能找出這些函數的文檔:如何使用CXML-STP的查找遞歸和查找遞歸如果

說我想在Stack Overflow的首頁找到第一個<div class="summary">。我可以在HTML樹是這樣的:

(defun get-page (url) 
    "Get STP(DOM alternative) representation of page" 
    (chtml:parse 
    (drakma:http-request url) 
    (cxml-stp:make-builder))) 

(get-page "http://stackoverflow.com") 

從這裏,雖然,我只是不知道find-recursivelyfind-recursively-if應該是什麼樣子與真正的參數。

編輯:解決的頭版上發現第一<div class="summary">所以使用find-recursively-if

(cxml-stp:find-recursively-if 
(lambda (node) 
    (and (typep node 'cxml-stp:element) 
    (equal (stp:local-name node) "div") 
    (equal (stp:attribute-value node "class") "summary"))) 
(get-page "http://stackoverflow.com")) 
+0

你能不能給你想要做什麼的例子嗎?看起來這些函數的工作方式與CL的'find'和'find-if'工作方式基本相同。 'item'可以是一個節點,在這種情況下,你可以直接找到節點,或者可以是例如一個數字,如果'key'函數需要一個節點並返回一個數字等。 –

回答

1

這些功能走節點樹,當你找到所需的節點(在find-recursively的情況下)返回或節點滿足謂詞(在find-recursively-if的情況下)。謂詞應該可以對節點做些什麼,但可以是任意的。例如,這裏的返回10點(通過使用一個謂詞,將返回true,在其10日的調用)的方式:

;; return the 10th node 
(let ((x 0)) 
    (cxml-stp:find-recursively-if 
    (lambda (node) 
    (= (incf x) 10)) 
    (get-page "http://stackoverflow.com"))) 

作爲一個更現實的例子,這裏是你如何能與當地的檢索元素命名"title"(請注意,您只能在elements使用local-name,而不是任意node S,所以:key功能是有點尷尬):

CL-USER> (cxml-stp:find-recursively 
      "title" 
      (get-page "http://stackoverflow.com") 
      :key (lambda (node) 
       (if (typep node 'cxml-stp:element) 
        (cxml-stp:local-name node) 
        "")) 
      :test 'string-equal) 
;=> 
;#.(CXML-STP:ELEMENT 
; #| :PARENT of type ELEMENT |# 
; :CHILDREN '(#.(CXML-STP:TEXT 
;     #| :PARENT of type ELEMENT |# 
;     :DATA "Stack Overflow")) 
; :LOCAL-NAME "title" 
; :NAMESPACE-URI "http://www.w3.org/1999/xhtml")