2014-03-03 79 views
4

我有一個XML文件,其中包含幾個嵌套組,例如,Elisp解析XML然後搜索特定值

<?xml encoding="utf-8"?> 

<MainNode 
    attribute1='values' 
    attribute2='values'/> 

    <SubNode1 attribute1='values'> 
     <Sub-SubNode1 attribute1='values'> ;; I want this value, only if 
      <Node-Of-Interest> ;; This exists 
       <Attribute1 value="value1"/> ;; And this is a specific value 
       <Attribute2 value="value2"/> 
      </Node-Of-Interest> 
     </Sub-SubNode1> 
    </SubNode1> 

    <SubNode1 attribute1='values'> 
     </Sub-SubNode1 attribute1='values'> 
    </SubNode1> 

</MainNode> 

該XML文件可能有幾個類型爲SubNode1的節點,它們的命名都相同;然而,我只對那些包含興趣節點的東西感興趣,特別是如果屬性Attribute1具有特定值,我想要Sub-SubNode1屬性1中的父屬性的值。

我已經用附帶的xml.el功能xml-parse-regionxml-get-attributesxml-get-children給我下面的結構的嘗試:

((SubNode1 ((attribute1 . "values")) " 
     " (Sub-SubNode1 ((attribute1 . "values")) " 
      " (Node-Of-Interest nil " 
       " (Attribute1 ((value . "value1"))) " 
       " (Attribute2 ((value . "value2"))) " 
      ") " 
     ") " 
    ") 
(SubNode1 ((attribute1 . "values")) " 
     " (Sub-SubNode1 ((attribute1 . "values"))) " 
    ")) 

我現在的問題是,如何走這個列表來查找值我會喜歡?

回答

2

只是一個基本的樹徑:

(setq tree 
     '((MainNode ((attribute1 . "values") 
        (attribute2 . "values")) 
     " " (SubNode1 ((attribute1 . "values")) 
       " " (Sub-SubNode1 ((attribute1 . "values")) 
           " " 
           (Node-Of-Interest 
           nil 
           " " 
           (Attribute1 ((value . "value1"))) 
           " " 
           (Attribute2 ((value . "value2"))) 
           " ") 
           " ") 
       " ") 
     " " (SubNode1 ((attribute1 . "values")) 
       " " (Sub-SubNode1 ((attribute1 . "values"))) 
       " ") 
     " "))) 

(defun my-recurse (lst fun) 
    (when (consp lst) 
    (append (and (funcall fun lst) (list lst)) 
      (my-recurse (car lst) fun) 
      (my-recurse (cdr lst) fun)))) 

(require 'cl-lib) 

(my-recurse 
tree 
(lambda (x) 
    (and (listp x) (symbolp (car x)) (listp (cdr x)) 
     (cl-find-if 
     (lambda (y) 
      (and (consp y) (eq (car y) 'Node-Of-Interest))) 
     x)))) 
;; => 
;; ((Sub-SubNode1 
;; ((attribute1 . "values")) 
;; " " (Node-Of-Interest 
;;  nil " " 
;;  (Attribute1 ((value . "value1"))) 
;;  " " 
;;  (Attribute2 ((value . "value2"))) 
;;  " ") 
;; " ")) 

順便說一句,你的XML根據Emacs的驗證被打破。