8

我想在 xml 树上组合三个 zip-filter 查询的结果。我正在解析的 XML 如下所示:

<someroot>
  <publication>
    <contributors>
      <person_name>
        <surname>Surname A</surname>
      </person_name>
      <person_name>
        <given_name>Given B</given_name>
        <surname>Surname B</surname>
        <suffix>Suffix B</suffix>
      </person_name>
    </contributors>
  </publication>
</someroot>

从这个例子中你可以看到<given_name>并且<suffix>是可选的——只有<surname>是必需的。这就是我的问题 - 如果我运行三个单独的查询,我得到的响应将彼此不一致:

(xml-> xml :publication :contributors :person_name :given_name text)
(xml-> xml :publication :contributors :person_name :surname text)
(xml-> xml :publication :contributors :person_name :suffix text)

运行这三个查询后,我将得到三个基数不匹配的序列;given_name并且suffix长度为 1 而surname长度为 2。这使我无法组合每个名称的组成部分。我需要编写一个查询,该查询将在序列构造期间执行此名称连接。

我正在查看非常稀疏的文档,clojure.contrib.zip-filter.xml并且无法弄清楚我该如何做到这一点(或者甚至可能)。不幸的是,我是 Clojure(和 Lisp)新手!谁能指出我如何编写一个连接其他三个嵌入式查询的查询?

4

2 回答 2

6

您可以一步获取所有人员子树(xml-> xmlzip :publication :contributors :person_name),然后获取名称部分(如果存在)(xml1-> personzip :surname 文本)并将它们组合成您想要的结果,如下所示:

(use 'clojure.contrib.zip-filter.xml)
(defn format-name
  [surname given suffix]
  (str surname (if given (str ", " given)) (if suffix (str ", " suffix))))
(defn get-names
  [xz] 
  (map (juxt 
         #(xml1-> % :surname text) 
         #(xml1-> % :given_name text) 
         #(xml1-> % :suffix text))
     (xml-> xz :publication :contributors :person_name)))
(let [x (clojure.zip/xml-zip (clojure.xml/parse "foo.xml"))] 
  (map (partial apply format-name) (get-names x)))

结果为(“姓 A”“姓 B,给定 B,后缀 B”)

于 2010-01-14T05:00:52.577 回答
2

我想另一种解决方案是

(xml-> xml :publication :contributors :person_name)

然后在以后处理每个<person_name>

于 2010-01-13T17:09:02.617 回答