Использование 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"))))]
      (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-> функциональных возможностей?

Файл полного кода с вызовом нерабочей функции:

ЦСИ / привет / 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 ответа

Вставленный вами код является правильным, и в этой трассировке стека нет проблемы.

конкретно ошибка показывает Unable to resolve symbol: result-data и из строки выше, что это выглядит, как будто он закрыл выражение, прежде чем он попал в строку с

 (pprint result-data)))

Это похоже на случай, когда в буфере выше синтаксическая ошибка. Например, если выше в программе был несбалансированный [ или же (,

потому что дополнительный вводный пара будет соответствовать этому и закончить выражение рано. Две ошибки после этого подтверждают это, заставляя меня думать, что он интерпретирует `(pprint result-data)))``как начало нового выражения с двумя дополнительными паренями в конце.

пытаться:

  • очистить буфер (в сидре нажмите , затем введите 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

так что это действительно похоже на проблему окружающей среды. Вот еще несколько вещей, чтобы проверить:

  • ответ находится в правильном пространстве имен
  • никакие дополнительные символы не добавляются или изменяются в процессе вырезания и вставки
  • paredit-mode не является автоматически закрывающим выражением, поскольку они вставляются в.
  • Менеджеры буфера обмена не вставили "умные цитаты".
  • код работает, если вы запускаете lean repl и вставьте строки в
  • lein check загружает файл без жалоб (кроме предупреждений об отражении)

Вставленный вами код работает на меня. Я думаю, что проблема должна быть связана с repl, который вы используете, со списком editor / 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!

Никаких ошибок компилятора (конечно, без тестовых данных, мы фактически не вызывали ни одну из ваших функций).

Похоже, проблема где-то в вашей среде. Если вы все очистите и начнете все сначала в новом проекте, вы должны увидеть те же результаты.

Другие вопросы по тегам