2013-05-28 14 views
23

Ho un blocco di JSON come questo:accesso tutti gli elementi nella JTOKEN, Json.NET

{ 
    "ADDRESS_MAP":{ 

     "ADDRESS_LOCATION":{ 
      "type":"separator", 
      "name":"Address", 
      "value":"", 
      "FieldID":40 
     }, 
     "LOCATION":{ 
      "type":"locations", 
      "name":"Location", 
      "keyword":{ 
       "1":"LOCATION1" 
      }, 
      "value":{ 
       "1":"United States" 
      }, 
      "FieldID":41 
     }, 
     "FLOOR_NUMBER":{ 
      "type":"number", 
      "name":"Floor Number", 
      "value":"0", 
      "FieldID":55 
     }, 
     "self":{ 
      "id":"2", 
      "name":"Address Map" 
     } 
    } 
} 

Come posso ottenere tutti gli elementi chiave che comprende questo token. Ad esempio, dal codice precedente desidero avere "ADRESS_LOCATION", "LOCATION", "FLOOR_NUMBER" e "self".

Grazie

risposta

39

Si può lanciare la vostra JToken ad un JObject e quindi utilizzare il metodo Properties() per ottenere un elenco delle proprietà dell'oggetto. Da lì, puoi ottenere i nomi piuttosto facilmente.

Qualcosa di simile a questo:

string json = 
@"{ 
    ""ADDRESS_MAP"":{ 

     ""ADDRESS_LOCATION"":{ 
      ""type"":""separator"", 
      ""name"":""Address"", 
      ""value"":"""", 
      ""FieldID"":40 
     }, 
     ""LOCATION"":{ 
      ""type"":""locations"", 
      ""name"":""Location"", 
      ""keyword"":{ 
       ""1"":""LOCATION1"" 
      }, 
      ""value"":{ 
       ""1"":""United States"" 
      }, 
      ""FieldID"":41 
     }, 
     ""FLOOR_NUMBER"":{ 
      ""type"":""number"", 
      ""name"":""Floor Number"", 
      ""value"":""0"", 
      ""FieldID"":55 
     }, 
     ""self"":{ 
      ""id"":""2"", 
      ""name"":""Address Map"" 
     } 
    } 
}"; 

JToken outer = JToken.Parse(json); 
JObject inner = outer["ADDRESS_MAP"].Value<JObject>(); 

List<string> keys = inner.Properties().Select(p => p.Name).ToList(); 

foreach (string k in keys) 
{ 
    Console.WriteLine(k); 
} 

uscita:

ADDRESS_LOCATION 
LOCATION 
FLOOR_NUMBER 
self 
+0

iterare su contenitori jobject invece di convertire a tipi risultati .NET in meno codice e, probabilmente, la migliore prestazione. Ho aggiunto una risposta per completare questo approccio che mostra questo approccio. – Ian

0

Se si conosce la struttura del JSON che si sta ricevendo quindi suggerirei avere una struttura di classe che rispecchia quello che stai ricevendo in JSON.

Poi si può chiamare il suo qualcosa di simile ...

AddressMap addressMap = JsonConvert.DeserializeObject<AddressMap>(json); 

(Dove JSON è una stringa contenente il JSON in questione)

Se non si conosce il formato del JSON voi dopo averlo ricevuto diventa un po 'più complicato e probabilmente avresti bisogno di analizzarlo manualmente.

check-out http://www.hanselman.com/blog/NuGetPackageOfTheWeek4DeserializingJSONWithJsonNET.aspx per ulteriori informazioni

13

Oltre alla risposta accettato vorrei dare una risposta che mostra come iterare direttamente sopra le collezioni Newtonsoft. Usa meno codice e immagino sia più efficiente in quanto non implica la conversione delle collezioni.

using Newtonsoft.Json; 
using Newtonsoft.Json.Linq; 
//Parse the data 
JObject my_obj = JsonConvert.DeserializeObject<JObject>(your_json); 

foreach (KeyValuePair<string, JToken> sub_obj in (JObject)my_obj["ADDRESS_MAP"]) 
{ 
    Console.WriteLine(sub_obj.Key); 
} 

ho iniziato a fare questo me stesso, perché JsonConvert deserializza automaticamente gli oggetti nidificati come JToken (che sono jobject, JValue, o JArray sotto credo).

Credo che i lavori di analisi in base ai seguenti principi:

  • Ogni oggetto viene astratto come JToken

  • Fusioni per jobject dove ci si aspetta un dizionario

  • Fusioni a JValue se il JToken rappresenta un nodo terminale ed è un valore

  • Trasmettere a JArray se la sua una serie

  • JValue.Value ti dà il tipo .NET è necessario

+0

Spiegazione molto utile dei principi di analisi del punto elenco, grazie. – stuzor

Problemi correlati