Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure数据压缩xml组合_Xml_Clojure_Zipper - Fatal编程技术网

Clojure数据压缩xml组合

Clojure数据压缩xml组合,xml,clojure,zipper,Xml,Clojure,Zipper,下面是一个例子来说明我想做什么: (ns sample (:require [clojure.zip :as zip] [clojure.data.zip.xml :refer [attr text xml-> xml1->]] [clojure.data.xml :as xml])) ;; From https://github.com/clojure/data.zip/blob/ca5a2efcc1c865baa25f904d

下面是一个例子来说明我想做什么:

(ns sample
  (:require [clojure.zip :as zip]
            [clojure.data.zip.xml :refer [attr text xml-> xml1->]]
            [clojure.data.xml :as xml]))

;; From https://github.com/clojure/data.zip/blob/ca5a2efcc1c865baa25f904d7d9f027809b8f738/src/test/clojure/clojure/data/zip/xml_test.clj
(def atom1 (xml/parse-str "<?xml version='1.0' encoding='UTF-8'?>
<feed xmlns='http://www.w3.org/2005/Atom'>
  <id>tag:blogger.com,1999:blog-28403206</id>
  <updated>2008-02-14T08:00:58.567-08:00</updated>
  <title type='text'>n01senet</title>
  <link rel='alternate' type='text/html' href='http://n01senet.blogspot.com/'/>
  <entry>
    <id>1</id>
    <published>2008-02-13</published>
    <title type='text'>clojure is the best lisp yet</title>
    <author><name>Chouser</name></author>
  </entry>
  <entry>
    <id>2</id>
    <published>2008-02-07</published>
    <title type='text'>experimenting with vnc</title>
    <author><name>agriffis</name></author>
  </entry>
</feed>
"))

(def atom1z (zip/xml-zip atom1))

(defn get-entries-titles [z]
  (xml-> z :entry :title text))

(defn get-entries [z]
  (xml-> z :entry))

(defn get-titles [z]
  (xml-> z :title))

(defn f1 []
  (-> atom1z get-entries-titles))

(defn f2 []
  (-> atom1z get-entries get-titles text))
运行
f2
会引发异常:

ClassCastException clojure.lang.LazySeq cannot be cast to clojure.lang.IFn  clojure.zip/node (zip.clj:67)
我的目标是将处理分为几个步骤:

  • 获取xml
  • 从xml获取条目
  • 从条目中获取标题
这样我就可以把事情分成不同的方法。例如,我可能需要获取属于XML不同部分的元素的不同属性,从而生成一个平面输出集合(例如,从上面的atom1中获取所有
元素,生成一个ID向量)

我希望有一些方法可以处理每种类型的节点(在上面的示例中,从
feed
获取ID,从
entry
获取ID),然后如上所述链接它们。也就是说,从上往下,从每一层挑选东西,如果需要,调用一个方法,以同样的方式(使用拉链)进一步处理孩子们

换句话说,我想:

  • 创建一个拉链
  • 将该拉链转发到其中一种处理方法
  • 将拉链移动到特定位置
  • 处理该位置
  • 使用步骤3中设置的位置,以相同的方式处理子级(步骤2-5)

  • 但是,根据
    f2
    中的异常情况,它看起来不是这样工作的。如何做到这一点?如果这不是使用clojure.data.zip.xml的方式,那么考虑到分解,建议使用哪种方式?

    我遇到了同样的问题。不能连续调用两个
    xml->
    运算符的原因很简单。正如Alex已经提到的那样,
    xml->
    返回一个seq。 你的问题有两个答案。 习惯处理树(或XML文档)的一种方法是处理树的每一级:

    (map (fn [entry] (xml-> entry :title text))
     (get-entries atom1z))
    

    如果您真正想要的是组合拉链,那么您必须编写一个宏来构造最终的拉链,就像get entries标题中的拉链一样。但是,只有在宏确实有帮助的情况下,才应该使用它。仔细想想。为了处理xml,您在clojure.data.zip.xml中缺少了什么?

    xml->
    接受一个拉链并返回一个拉链序列。如果您想编写这样的函数,您需要重写它们以接受一个拉链序列。谢谢@Alex,这当然有道理(我甚至需要
    xml1->
    …)。是否愿意发布一个我可以接受的答案?这是推荐的方法吗?有什么替代方法吗?你通常是如何处理这些事情的?
    (map (fn [entry] (xml-> entry :title text))
     (get-entries atom1z))