Clojure中XML文档的多个变体

Clojure中XML文档的多个变体,xml,clojure,zipper,Xml,Clojure,Zipper,我正在尝试clojure(第一次)做一个简单的项目。我需要更新给定csv文件的xml树。我正在逐行读取csv文件,提取一些值,循环一个给定值的节点,并插入一个子节点和另一个值 这在我第一次插入项目时效果很好。第二次我得到一个NullPointerException(没有跟踪)。我从insert child得到的返回值中查找根节点,并将该根节点传递给下一个循环。不知何故,第二次插入在该根元素上失败。有人看到这里出了什么问题吗?或者对这段代码的总体反馈,因为这是我第一次尝试编写Clojure (re

我正在尝试clojure(第一次)做一个简单的项目。我需要更新给定csv文件的xml树。我正在逐行读取csv文件,提取一些值,循环一个给定值的节点,并插入一个子节点和另一个值

这在我第一次插入项目时效果很好。第二次我得到一个NullPointerException(没有跟踪)。我从insert child得到的返回值中查找根节点,并将该根节点传递给下一个循环。不知何故,第二次插入在该根元素上失败。有人看到这里出了什么问题吗?或者对这段代码的总体反馈,因为这是我第一次尝试编写Clojure

(require 'clojure.string)
(require '[clojure.java.io :as io])
(require '[clojure.xml :as xml])
(require '[clojure.zip :as zip])
(require '[clojure.data.zip.xml :as zf])

(def business-object-config (xml/parse "BusinessObject.config"))
(def zipped (zip/xml-zip business-object-config ))

(defn sql-table-name [table-name]
  (second (re-matches #"(.*?)(Base|ExtensionBase|$)" table-name)))

(defn insert-sqlpropertyname-elem [loc name]
  (zip/root (zip/insert-child loc {:tag :SqlPropertyName :content [name]})))

(defn get-entity-node [table-name crm-name business-objects]
  (first (zf/xml-> business-objects :Entities
    :Entity [:CrmName (zf/text= (clojure.string/lower-case (sql-table-name table-name)))]
    :EntityItems
    :EntityItem [:CrmPropertyName (zf/text= (clojure.string/lower-case crm-name))])))

(defn process-line [line business-objects]
  (let [{crm-name 0 table-name 1 sql-name 6} (clojure.string/split line #";")
        node (get-entity-node table-name crm-name business-objects)]
    (insert-sqlpropertyname-elem node sql-name)))

(defn process-csv []
  (with-open
    [rdr (io/reader "input.csv")]
      (loop [lines (vec (take 5 (rest (line-seq rdr))))
             index (dec (count lines))
             boc zipped]
        (if (neg? index)
          boc
        (recur lines (dec index) (process-line (nth lines index) boc))))))

(spit "out.xml" (with-out-str (xml/emit (process-csv)) :pad true))

不是很有帮助的NPE通常意味着你在某个地方跑掉了


我怀疑您不需要在insert sqlpropertyname elem中调用
zip/root

不太有帮助的NPE通常意味着你在某个地方跑掉了


我怀疑您不需要在insert sqlpropertyname elem中调用
zip/root

好的,我不知道这是不是正确的方法,但是如果我在insert child的结果上调用root,然后在root上调用xml zip,那么一切都正常。不知道在每次变异后压缩整个结构是否是最佳做法?

好的,我不知道这是否是正确的方法,但是如果我对insert child的结果调用root,然后对root调用xml zip,一切都会正常工作。不知道每次变异后压缩整个结构是否是最佳做法?

问题与插入子函数的返回值有关。如果我不调用结构上的zip/root并使用get entity节点函数进行查询,它将返回nil。如果我调用zip/root,我将得到NPE。因此,insert-child的返回值在某种程度上与原始zippers树的数据结构不同。因此,更准确地说,如何将从insert子级返回的数据结构转换为可以使用xml查询的数据结构->?如何将
(重现行(dec索引)(流程行(n行索引)boc))
替换为
(do(流程行(n行索引)boc)(重现行(dec索引)boc))
问题与插入子函数的返回值有关。如果我不调用结构上的zip/root并使用get entity节点函数进行查询,它将返回nil。如果我调用zip/root,我将得到NPE。因此,insert-child的返回值在某种程度上与原始zippers树的数据结构不同。因此,更准确地说,如何将从insert子级返回的数据结构转换为可以使用xml查询的数据结构->?如何将
(重现行(dec索引)(流程行(n行索引)boc))
替换为
(do(流程行(n行索引)boc)(重现行(dec索引)boc))