0

ジッパーを使用して石鹸データを解析するコードがあります。フォーマットすると、期待どおりに機能します

(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 ステートメントに移動すると、コンパイルに失敗し、次のエラーが発生します (ブラケットが一致することを 3 回確認しました)。

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=> 

次のように、let ステートメントに xml-z/xml-> 呼び出しを入れるようにコードが変更されました。

(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"]])
4

2 に答える 2

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!

コンパイラ エラーはありません (もちろん、テスト データがなければ、実際に関数を呼び出すこともありませんでした)。

問題はあなたの環境のどこかにあるようです。すべてを一掃し、新しいプロジェクトで新たに開始すると、同じ結果が表示されるはずです。

于 2016-08-17T16:22:19.033 に答える
1

貼り付けたコードは正しく、そのスタックトレースに貼り付けられた問題はありません。

具体的にはエラーが表示Unable to resolve symbol: result-dataされ、上記の行から、次の行に到達する前に式を閉じたように見えます

 (pprint result-data)))

これは、バッファの上位に構文エラーがある場合のように聞こえます。たとえば、プログラムの上位にアンバランスな[orがあった場合(

余分な開始括弧がこれに一致し、式を早期に終了させるためです。その後の 2 つのエラーは、これに証拠を追加し、`(pprint result-data)))` を最後に 2 つの追加のかっこを持つ新しい式の開始として解釈していると思わせます。

試す:

  • バッファをクリアして(ciderを押して,から入力clear)、もう一度試してください。
  • nrepl を再起動してみて (サイダー プレスで,typre 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 は、貼り付けられているため、自動終了式ではありません。
  • クリップボード マネージャーによって挿入された「スマート クォート」はありません。
  • 行を実行lean replして貼り付けると、コードが機能します
  • lein check苦情なしでファイルをロードします(リフレクション警告を除く)
于 2016-08-16T21:27:44.870 に答える