使用emacs elisp解析XML并查找嵌套属性

使用emacs elisp解析XML并查找嵌套属性,xml,parsing,emacs,lisp,elisp,Xml,Parsing,Emacs,Lisp,Elisp,我有一些xml,如下所示: ((grammar nil " " (l nil " " (f ((form . "paradāra")) (s ((stem . ""))) (m ((meaning . "anothers wife; adultery")))) " " (f ((form . "abhimarśeṣu")) (s ((stem . &quo

我有一些xml,如下所示:

((grammar nil "
" (l nil "
" (f ((form . "paradāra")) (s ((stem . ""))) (m ((meaning . "anothers wife; adultery")))) "

" (f ((form . "abhimarśeṣu")) (s ((stem . "") (meaning . ""))) (m ((meaning . "")))) "
" (f ((form . "pravṛttān")) (s ((stem . "") (meaning . ""))) (m ((meaning . "")))) "
" (f ((form . "mahipatis")) (s ((stem . "") (meaning . ""))) (m ((meaning . "")))) "
") "
" (l nil "
" (f ((form . "udvejana")) (s ((stem . "udvejana") (meaning . "agitation, fear"))) (m ((meaning . "")))) "

" (f ((form . "karais")) (na nil (ins nil) (pl nil) (mas nil)) (s ((stem . "kara#1") (meaning . "action"))) (m ((meaning . "by action")))) "

" (f ((form . "daṇḍais")) (na nil (ins nil) (pl nil) (mas nil)) (na nil (ins nil) (pl nil) (neu nil)) (s ((stem . "daṇḍa") (meaning . "punishment"))) (m ((meaning . "by punishment")))) "

" (f ((form . "cihnayitvā")) (s ((stem . "") (meaning . "having marked"))) (m ((meaning . "")))) "

" (f ((form . "pravāsayet")) (v nil (cj nil (ca nil)) (sys nil (prs nil (md nil (op nil)) (para nil))) (np nil (sg nil) (trd nil))) (s ((stem . "pravas"))) (m ((meaning . "to put on, dress")))) "

") "
"))

现在我通过运行(xml解析区域)将其转换为S表达式。它返回如下内容:

((grammar nil "
" (l nil "
" (f ((form . "paradāra")) (s ((stem . ""))) (m ((meaning . "anothers wife; adultery")))) "

" (f ((form . "abhimarśeṣu")) (s ((stem . "") (meaning . ""))) (m ((meaning . "")))) "
" (f ((form . "pravṛttān")) (s ((stem . "") (meaning . ""))) (m ((meaning . "")))) "
" (f ((form . "mahipatis")) (s ((stem . "") (meaning . ""))) (m ((meaning . "")))) "
") "
" (l nil "
" (f ((form . "udvejana")) (s ((stem . "udvejana") (meaning . "agitation, fear"))) (m ((meaning . "")))) "

" (f ((form . "karais")) (na nil (ins nil) (pl nil) (mas nil)) (s ((stem . "kara#1") (meaning . "action"))) (m ((meaning . "by action")))) "

" (f ((form . "daṇḍais")) (na nil (ins nil) (pl nil) (mas nil)) (na nil (ins nil) (pl nil) (neu nil)) (s ((stem . "daṇḍa") (meaning . "punishment"))) (m ((meaning . "by punishment")))) "

" (f ((form . "cihnayitvā")) (s ((stem . "") (meaning . "having marked"))) (m ((meaning . "")))) "

" (f ((form . "pravāsayet")) (v nil (cj nil (ca nil)) (sys nil (prs nil (md nil (op nil)) (para nil))) (np nil (sg nil) (trd nil))) (s ((stem . "pravas"))) (m ((meaning . "to put on, dress")))) "

") "
"))
我现在要做的是提取所有以(s…)开头的子节点,并将它们收集到一个单独的缓冲区中。比如:

(s ((stem . "udvejana") (meaning . "agitation, fear")))

代码是什么样子的?你在树上散步吗?昨天我尽可能地走到了第一个(l…)节点,但由于停电,我丢失了代码。希望你们当中有人能提出一些建议

您只需要基本的递归:

(defun rec-filter (predicate seq &optional acc)
  (cond ((null seq)
         acc)
        ((consp seq)
         (append (rec-filter predicate (car seq) nil)
                 (rec-filter predicate (cdr seq) nil)
                 (if (funcall predicate seq)
                     (cons seq acc)
                   acc)))
        (t
         acc)))

(rec-filter
 (lambda (x) (eq (car x) 's))
 tree)
;; =>
;; ((s ((stem . "")))
;;  (s ((stem . "")
;;      (meaning . "")))
;;  (s ((stem . "")
;;      (meaning . "")))
;;  (s ((stem . "")
;;      (meaning . "")))
;;  (s ((stem . "udvejana")
;;      (meaning . "agitation, fear")))
;;  (s ((stem . "kara#1")
;;      (meaning . "action")))
;;  (s ((stem . "daṇḍa")
;;      (meaning . "punishment")))
;;  (s ((stem . "")
;;      (meaning . "having marked")))
;;  (s ((stem . "pravas"))))