2013-07-21 11 views
8

Dato il codice:JsonProvider "Questo non è un'espressione costante o attributo valido personalizzato valore"

#if INTERACTIVE 
#r "bin\Debug\FSharp.Data.dll" 

#endif 

open System 
open FSharp.Data 
open FSharp.Data.Json 

let testJson = """{ "workingDir":"hello", "exportDir":"hi there", "items":[{ "source":"", "dest":"", "args": {"name":"that"} }] }""" 

//here is where i get the error 
let Schema = JsonProvider<testJson> 

L'ultima riga continua a darmi l'errore "Questo non è un'espressione costante o valida personalizzato valore di attributo" - - cosa significa? Come posso leggere questo JSON?

risposta

14

La stringa deve essere contrassegnata come costante. Per fare ciò, utilizzare the [<Literal>] attribute. Inoltre, il provider di tipo crea un tipo, non un valore, quindi è necessario utilizzare type invece di let:

open FSharp.Data 

[<Literal>] 
let testJson = """{ "workingDir":"hello", "exportDir":"hi there", "items":[{ "source":"", "dest":"", "args": {"name":"that"} }] }""" 

type Schema = JsonProvider<testJson> 
+0

Grazie per queste informazioni. Sono curioso di sapere se qualcuno può spiegare in dettaglio perché devi marcare un valore che è già immutabile come costante. Cosa sta succedendo davvero qui? EDIT: non importa, ho capito. Ovviamente questo deve risolvere tutti in fase di 'compilazione', non in runtime. – jackmott

0

Il JsonProvider può essere visualizzato come un parser JSON parametrizzato (più il tipo di dati che produce il parser) che è specializzato in fase di compilazione.

Il parametro che gli viene assegnato (una stringa o un percorso per il file JSON) definisce la struttura dei dati JSON, uno schema se lo desideri. Ciò consente al provider di creare un tipo che avrà tutte le proprietà che i dati JSON devono avere, staticamente, e l'insieme di tali proprietà (insieme ai rispettivi tipi) sono definiti (in realtà dedotti da) con l'esempio JSON che dai a il fornitore.

Quindi il modo corretto di usare il JsonProvider è mostrato in uno degli esempi della documentazione:

// generate the type with a static Parse method with help of the type provider 
type Simple = JsonProvider<""" { "name":"John", "age":94 } """> 
// call the Parse method to parse a string and create an instance of your data 
let simple = Simple.Parse(""" { "name":"Tomas", "age":4 } """) 
simple.Age 
simple.Name 

L'esempio è stato preso da here.

+0

Sì, tranne che si * può * utilizzare una variabile, deve solo essere contrassegnato come costante. – svick

+1

@svick, sì, c'è l'attributo 'Literal' che consente di creare i cosiddetti letterali con nome. Ma come dici tu, rende la 'variabile' una 'costante', che è un po 'contraddittoria, non sei d'accordo? :) – MisterMetaphor

+0

Sì, ma non conosco un buon termine che descriva entrambe le variabili e le costanti. – svick

Problemi correlati