3

I have this function which in a xml structure gives me the id of a parent node.

(ns foo.core
  (:require [clojure.data.zip.xml :as cdzx]))

(defn id-of-parent [zipper child-id node1 node2 node3 node4]
  (cdzx/xml-> zipper node1 node2 node3 node4
    (cdzx/attr= :Id child-id) zip/up zip/up (cdzx/attr :Id)))

It would be called like

(id-of-parent zipper child-id :Foos :Foo :Bars :Bar)

I would now like to make this function more general by replacing the four "node" with a simple "& path" so I can use any number of nodes to set a path.

(defn id-of-parent [zipper child-id & path]
  (cdzx/xml-> zipper ????path????
    (cdzx/attr= :Id child-id) zip/up zip/up (cdzx/attr :Id)))

What is the proper way of unrolling the sequence of keywords to single keywords?

4

3 回答 3

4

syntax-quote 函数的unquote-splicing 特性几乎总是用于构建宏中的函数调用,尽管它恰好适合构建一般的函数调用。

(defn id-of-parent [zipper child-id & path]
        (apply cdzx/xml-> `(~zipper ~@path
          ~(cdzx/attr= :Id child-id) ~zip/up ~zip/up ~(cdzx/attr :Id))))

因为xml->是一个函数而不是一个宏,所以您可以使用 apply 构建对它的调用

于 2012-08-02T20:57:37.127 回答
1

您可以使用apply.

(defn id-of-parent
  [zipper child-id & path]
  (->> [(cdzx/attr= :Id child-id) zip/up zip/up (cdzx/attr :Id)]
    (concat path)
    (apply cdzx/xml-> zipper)))
于 2012-08-03T06:21:36.990 回答
1

应用可以像这样使用:

(defn id-of-parent
  [zipper child-id & path]
  (let [pred [path (cdzx/attr= :Id child-id) zip/up zip/up (cdzx/attr :Id)]]
    (apply cdzx/xml-> zipper (flatten pred))))
于 2012-08-03T06:32:01.817 回答