Elisp Parse XML然后搜索特定值

时间:2014-03-03 15:29:19

标签: xml emacs 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"))) "
    "))

我现在的问题是,如何走这个列表找到我想要的值?

1 个答案:

答案 0 :(得分: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验证器被破坏了。