使用xml->让我们

时间:2016-08-16 21:07:39

标签: xml clojure zipper

我有一些代码,用拉链解析肥皂数据。当我格式化它时,它按预期的方式工作

(defn parse-data
 [raw-data]
 (let [soap-data (:body raw-data)
        soap-envelope (zip/xml-zip
                    (xml/parse
                      (java.io.ByteArrayInputStream. (.getBytes (str soap-data) "UTF-8"))))]
      (pprint (xml-z/xml-> soap-envelope :soap:Envelope :soap:Body :Tag1 :Tag2))))

打印出预期结果。但是,当我将XML解析移动到let语句时,它无法编译,并出现以下错误(我已经三次检查我的括号匹配)

RuntimeException EOF while reading, starting at line 3  clojure.lang.Util.runtimeException (Util.java:221)
jcode.oc-drift.aquisition=>       (pprint result-data)))

CompilerException java.lang.RuntimeException: Unable to resolve symbol: result-data in this context, compiling:(/tmp/form-init6714472131112461091.clj:1:1) 
RuntimeException Unmatched delimiter: )  clojure.lang.Util.runtimeException (Util.java:221)

RuntimeException Unmatched delimiter: )  clojure.lang.Util.runtimeException (Util.java:221)
jcode.oc-drift.aquisition=> 

代码已更改为放入xml-z / xml->调用let语句,如下所示

(defn parse-data
 [raw-data]
 (let [soap-data (:body raw-data)
        soap-envelope (zip/xml-zip
                    (xml/parse
                      (java.io.ByteArrayInputStream. (.getBytes (str soap-data) "UTF-8"))))
        result-data (xml-z/xml-> soap-envelope :soap:Envelope :soap:Body :GetNextTripsForStopResponse :GetNextTripsForStopResult)]
      (pprint result-data)))

这是let形式的错误,还是我遗漏了xml->的行为?功能?

带有非工作函数的完整代码文件:

的src /你好/ core.clj:

(ns hello.core
 (:require [clj-http.client :as http-client]
            [clojure.zip :as zip]
            [clojure.xml :as xml]
            [clojure.data.xml :as xml-data]
            [clojure.data.zip.xml :as xml-z]))

(use 'clojure.pprint)

(def app-id "redacted")
(def api-key "redacted")
(def post-data {:apiKey api-key :appID app-id})

(defn get-data
 [post-data function]
 "function is a string with the api function to be called"
  (let [url (str "redacted" function)]
   (http-client/post url {:form-params post-data})))

(defn parse-data
 [raw-data]
 (let [soap-data (:body raw-data)
        soap-envelope (zip/xml-zip
                    (xml/parse
                      (java.io.ByteArrayInputStream. (.getBytes (str soap-data) "UTF-8"))))
        result-data (xml-z/xml-> soap-envelope :soap:Envelope :soap:Body :GetNextTripsForStopResponse :GetNextTripsForStopResult)]
      (pprint result-data)))

project.clj:

(defproject hello "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :main hello.core
  :dependencies [[org.clojure/clojure "1.7.0"]                 
                 [org.clojure/data.xml "0.0.8"]
                 [org.clojure/data.zip "0.1.2"]
                 [clj-http "2.2.0"]])

2 个答案:

答案 0 :(得分:1)

您粘贴的代码是正确的,并且没有在该堆栈跟踪中粘贴的问题。

具体而言,错误显示Unable to resolve symbol: result-data,并且从上面的一行看起来它在表达式到达行之前关闭了表达式

 (pprint result-data)))

这听起来像缓冲区中存在更高语法错误的情况。例如,如果程序中的较高位置存在不平衡[(

因为额外的开放paren会匹配这个,并提前结束表达。之后的两个错误为此添加了证据,使我认为它将`(pprint result-data))``解释为一个新表达式的开头,最后有两个额外的parens。

尝试:

  • 清除缓冲区(在苹果酒中按,然后键入clear)并再次尝试。
  • 尝试重新启动nrepl(在苹果酒中按,然后选择restart)然后重试。

运行代码在repl中运行和从文件中进行评估时都是正确的(这些是完全相同的操作)

hello.core> (defn parse-data
              [raw-data]
              (let [soap-data (:body raw-data)
                    soap-envelope (zip/xml-zip
                                   (xml/parse
                                    (java.io.ByteArrayInputStream. (.getBytes (str soap-data) "UTF-8"))))]
                (pprint (xml-z/xml-> soap-envelope :soap:Envelope :soap:Body :Tag1 :Tag2))))
#'hello.core/parse-data
hello.core> (defn parse-data
              [raw-data]
              (let [soap-data (:body raw-data)
                    soap-envelope (zip/xml-zip
                                   (xml/parse
                                    (java.io.ByteArrayInputStream. (.getBytes (str soap-data) "UTF-8"))))
                    result-data (xml-z/xml-> soap-envelope :soap:Envelope :soap:Body :GetNextTripsForStopResponse :GetNextTripsForStopResult)]
                (pprint result-data)))
#'hello.core/parse-data

所以这看起来真的像环境问题。以下是一些需要检查的内容:

  • repl位于正确的命名空间
  • 在剪切和粘贴过程中没有添加或更改额外字符
  • paredit-mode不会在粘贴表达式时自动关闭表达式。
  • no"聪明的报价"已被剪贴板管理员插入。
  • 如果您运行lean repl并将行粘贴到
  • 中,则代码可以正常工作
  • lein check加载文件时没有投诉(反映警告除外)

答案 1 :(得分:1)

你粘贴的代码对我有用。我认为问题必须与您正在使用的repl,编辑器/ repl组合或其他内容相关。创建一个新项目并粘贴以下内容:

> lein new app hello

然后编辑2个文件:

project.clj

(defproject hello 
  "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :main hello.core
  :dependencies [[org.clojure/clojure "1.7.0"]                 
                 [org.clojure/data.xml "0.0.8"]
                 [org.clojure/data.zip "0.1.2"]
                 [clj-http "2.2.0"]] )

src/hello/core.clj

(ns hello.core
  (:require [clj-http.client :as http-client]
            [clojure.zip :as zip]
            [clojure.xml :as xml]
            [clojure.data.xml :as xml-data]
            [clojure.data.zip.xml :as xml-z]))

(use 'clojure.pprint)

(def app-id "redacted")
(def api-key "redacted")
(def post-data {:apiKey api-key :appID app-id})

(defn get-data
 [post-data function]
 "function is a string with the api function to be called"
  (let [url (str "redacted" function)]
   (http-client/post url {:form-params post-data})))

(defn parse-data
 [raw-data]
 (let [soap-data (:body raw-data)
        soap-envelope (zip/xml-zip
                    (xml/parse
                      (java.io.ByteArrayInputStream. (.getBytes (str soap-data) "UTF-8"))))
        result-data (xml-z/xml-> soap-envelope :soap:Envelope :soap:Body :GetNextTripsForStopResponse :GetNextTripsForStopResult)]
      (pprint result-data)))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "Hello, World!"))

然后从命令行运行

> lein run    
Hello, World!

没有编译错误(当然,没有测试数据,我们也没有实际调用任何函数)。

看起来问题出现在您的环境中。如果你清理掉所有东西并在新项目中重新开始,你应该看到相同的结果。