我想在XML树三个拉链过滤查询的结果结合起来。我解析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_namesuffix将长度为1,而surname将是长度2。这使得它不可能对我来说,每一个名字的组件相结合。我需要编写将序列构造期间执行此名称级联单个查询。

我看的很稀疏文档clojure.contrib.zip-filter.xml和想不通我怎么能做到这一点(或者如果它甚至有可能)。不幸的是我是一个Clojure的(和Lisp)新手!任何人都可以指出我如何可以编写一个查询,将串连其他三个嵌入式查询?

有帮助吗?

解决方案

您可以得到所有的人子树在一个步骤(XML-> xmlzip:刊物:提供者:PERSON_NAME)然后获取名称部分,如果他们存在(xml1-> personzip:姓文本),并将其合并到你想要的结果像这样:

(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”)

其他提示

我想的替代解决方案是

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

和再后来处理每个<person_name>

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top