2016-05-16 19 views
-2

Ich habe ein Problem bei der Validierung von Clojure prismatischen Schema. Hier ist der Code.Validierung von Clojure Schema

:Some_Var1 {:Some_Var2 s/Str 
        :Some_Var3 (s/conditional 
         #(= "mytype1" (:type %)) s/Str 
         #(= "mytype2" (:type %)) s/Str 
       )} 

Ich versuche, es zu validieren mit dem Code:

"Some_Var1": { 
    "Some_Var2": "string", 
"Some_Var3": {"mytype1":{"type":"string"}} 
    } 

aber es wirft mir einen Fehler:

{ 
    "errors": { 
    "Some_Var1": { 
     "Some_Var3": "(not (some-matching-condition? a-clojure.lang.PersistentArrayMap))" 
    } 
    } 
} 

Es ist ein sehr einfaches Code den ich versuche zu validieren . Ich bin sehr neu in clojure und versuche immer noch, Grundlagen davon zu lernen.

Danke,

Antwort

2

Willkommen bei Clojure! Es ist eine großartige Sprache.

In Clojure, ein Schlüsselwort und eine Zeichenfolge sind verschiedene Typen, d. H. :type ist nicht das gleiche "type". Zum Beispiel:

user=> (:type {"type" "string"}) 
nil 
(:type {:type "string"}) 
"string" 

Aber ich denke, es gibt eine tiefere Frage hier: aus Blick auf Ihre Daten, es scheint, dass Sie die Typinformationen in den Daten codieren wollen selbst und dann auf diese Informationen überprüfen basiert. Es könnte möglich sein, aber es wäre eine ziemlich fortgeschrittene Verwendung des Schemas. Schema wird typischerweise verwendet, wenn die Typen vor dem Typ bekannt sind, z. Daten wie:

(require '[schema.core :as s]) 
(def data 
    {:first-name "Bob" 
    :address {:state "WA" 
      :city "Seattle"}}) 

(def my-schema 
    {:first-name s/Str 
    :address {:state s/Str 
      :city s/Str}}) 

(s/validate my-schema data) 

Ich würde vorschlagen, dass auf verschlüsselte Art Informationen, wenn Sie Innovationen zusätzlich benötigen, ist es wahrscheinlich einfacher sein, würde eine benutzerdefinierte Funktion für das zu schreiben.

Hoffe, dass hilft!

Update:

Ein Beispiel zeigt, wie conditional Werke, hier ist ein Schema, das validiert, aber auch dies ist ein nicht-idiomatische Verwendung von Schema:

(s/validate 
{:some-var3 
(s/conditional 
;; % is the value: {"mytype1" {"type" "string"}} 
;; so if we want to check the "type", we need to first 
;; access the "mytype1" key, then the "type" key 
#(= "string" (get-in % ["mytype1" "type"])) 
;; if the above returns true, then the following schema will be used. 
;; Here, I've just verified that 
;; {"mytype1" {"type" "string"}} 
;; is a map with key strings to any value, which isn't super useful 
{s/Str s/Any} 
)} 
{:some-var3 {"mytype1" {"type" "string"}}}) 

Ich hoffe, das hilft.

+0

Vielen Dank für Ihre Antwort, aber ich bin immer noch nicht in der Lage, das Problem zu lösen. Können Sie mir bitte sagen, welche Art von strukturierter Eingabe der bedingte Typ will? wie man mytype1 in einer Bedingungsanweisung auswählt. – peejain

+0

Mit 'conditional' wird jede Klausel der Reihe nach ausgewertet. In Ihrem Beispiel hat% den folgenden Wert: {"mytype1" {"type" "string"}} Beachten Sie, dass dieser Wert nicht den Schlüssel ': type' hat und, auch wenn,': type 'maps to' "string" 'anstelle von' "mytype" '. – bbrinck