Использование 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!
Никаких ошибок компилятора (конечно, без тестовых данных, мы фактически не вызывали ни одну из ваших функций).
Похоже, проблема где-то в вашей среде. Если вы все очистите и начнете все сначала в новом проекте, вы должны увидеть те же результаты.