2013-08-14 13 views
27

Jestem nowy w pracy z danymi JSON.Jak odserializować dane JSON?

Czytam dane z usługi internetowej. Dane zapytań odsyłane jest następujący:

[["B02001_001E","NAME","state"], 
["4712651","Alabama","01"], 
["691189","Alaska","02"], 
["6246816","Arizona","04"], 
["18511620","Florida","12"], 
["9468815","Georgia","13"], 
["1333591","Hawaii","15"], 
["1526797","Idaho","16"], 
["3762322","Puerto Rico","72"]] 

Czy istnieje sposób deserializowania te dane w taki sposób, że obiekt bazowy zostanie wygenerowany bez mi najpierw zdefiniować, co jest jak przedmiot? W powyższym przykładzie, celem jest określona w pierwszym rzędzie:

  ["B02001_001E","NAME","state"], 

Ogólnie serwis internetowy powróci danych zapytań, sformatowanych w dwuwymiarowej tablicy JSON gdzie pierwszy rząd przedstawiono nazwy kolumn i kolejne rzędy określają wartości danych .

Odpowiedz

43

Możesz deserializować to bardzo łatwo. Struktura danych w języku C# to tylko List<string[]>, więc możesz po prostu zrobić;

List<string[]> data = JsonConvert.DeserializeObject<List<string[]>>(jsonString); 

Powyższy kod zakłada, że ​​używasz json.NET.

EDYCJA: Zwróć uwagę, że json jest technicznie tablicą tablic ciągów. Wolę używać List<string[]> dla mojej własnej deklaracji, ponieważ jest ona bardziej intuicyjna. Nie spowoduje żadnych problemów dla json.NET, jeśli chcesz, aby był to tablica tablic ciągów, musisz zmienić typ na (myślę) string[][], ale są pewne śmieszne małe elementy z poszarpanymi i 2D tablicami w C# o których tak naprawdę nie wiem, więc nie przejmuję się tym tutaj.

0

Krok 1: Przejdź do json.org, aby znaleźć bibliotekę JSON dla dowolnej technologii, której używasz do połączenia się z tą usługą sieciową. Pobierz i połącz z tą biblioteką.

Krok 2: Załóżmy, że używasz języka Java. należałoby użyć JSONArray tak:

JSONArray myArray=new JSONArray(queryResponse); 
for (int i=0;i<myArray.length;i++){ 
    JSONArray myInteriorArray=myArray.getJSONArray(i); 
    if (i==0) { 
     //this is the first one and is special because it holds the name of the query. 
    }else{ 
     //do your stuff 
     String stateCode=myInteriorArray.getString(0); 
     String stateName=myInteriorArray.getString(1); 
    } 
} 
29

Jeśli używasz .NET 4.5 można również użyć standardowego .Net json serializatora:

using System.Runtime.Serialization.Json; 
...  
Stream jsonSource = ...; // serializer will read data stream 
var s = new DataContractJsonSerializer(typeof(string[][])); 
var j = (string[][])s.ReadObject(jsonSource); 

w .NET 4.5 i starszych można użyć klasy JavaScriptSerializer:

using System.Web.Script.Serialization; 
... 
JavaScriptSerializer serializer = new JavaScriptSerializer(); 
string[][] list = serializer.Deserialize<string[][]>(json); 
0

Możesz napisać własny parser JSON i uczynić go bardziej uniwersalnym w oparciu o twoje wymagania. Oto jeden, który ładnie służył mojemu celowi, nadzieja też ci pomoże.

class JsonParsor 
{ 
    public static DataTable JsonParse(String rawJson) 
    { 
     DataTable dataTable = new DataTable(); 
     Dictionary<string, string> outdict = new Dictionary<string, string>(); 
     StringBuilder keybufferbuilder = new StringBuilder(); 
     StringBuilder valuebufferbuilder = new StringBuilder(); 
     StringReader bufferreader = new StringReader(rawJson); 
     int s = 0; 
     bool reading = false; 
     bool inside_string = false; 
     bool reading_value = false; 
     bool reading_number = false; 
     while (s >= 0) 
     { 
      s = bufferreader.Read(); 
      //open JSON 
      if (!reading) 
      { 
       if ((char)s == '{' && !inside_string && !reading) 
       { 
        reading = true; 
        continue; 
       } 
       if ((char)s == '}' && !inside_string && !reading) 
        break; 
       if ((char)s == ']' && !inside_string && !reading) 
        continue; 
       if ((char)s == ',') 
        continue; 
      } 
      else 
      { 
       if (reading_value) 
       { 
        if (!inside_string && (char)s >= '0' && (char)s <= '9') 
        { 
         reading_number = true; 
         valuebufferbuilder.Append((char)s); 
         continue; 
        } 
       } 
       //if we find a quote and we are not yet inside a string, advance and get inside 
       if (!inside_string) 
       { 
        if ((char)s == '\"' && !inside_string) 
         inside_string = true; 
        if ((char)s == '[' && !inside_string) 
        { 
         keybufferbuilder.Length = 0; 
         valuebufferbuilder.Length = 0; 
           reading = false; 
           inside_string = false; 
           reading_value = false; 
        } 
        if ((char)s == ',' && !inside_string && reading_number) 
        { 
         if (!dataTable.Columns.Contains(keybufferbuilder.ToString())) 
          dataTable.Columns.Add(keybufferbuilder.ToString(), typeof(string)); 
         if (!outdict.ContainsKey(keybufferbuilder.ToString())) 
          outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString()); 
         keybufferbuilder.Length = 0; 
         valuebufferbuilder.Length = 0; 
         reading_value = false; 
         reading_number = false; 
        } 
        continue; 
       } 

       //if we reach end of the string 
       if (inside_string) 
       { 
        if ((char)s == '\"') 
        { 
         inside_string = false; 
         s = bufferreader.Read(); 
         if ((char)s == ':') 
         { 
          reading_value = true; 
          continue; 
         } 
         if (reading_value && (char)s == ',') 
         { 
          //put the key-value pair into dictionary 
          if(!dataTable.Columns.Contains(keybufferbuilder.ToString())) 
           dataTable.Columns.Add(keybufferbuilder.ToString(),typeof(string)); 
          if (!outdict.ContainsKey(keybufferbuilder.ToString())) 
          outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString()); 
          keybufferbuilder.Length = 0; 
          valuebufferbuilder.Length = 0; 
          reading_value = false; 
         } 
         if (reading_value && (char)s == '}') 
         { 
          if (!dataTable.Columns.Contains(keybufferbuilder.ToString())) 
           dataTable.Columns.Add(keybufferbuilder.ToString(), typeof(string)); 
          if (!outdict.ContainsKey(keybufferbuilder.ToString())) 
           outdict.Add(keybufferbuilder.ToString(), valuebufferbuilder.ToString()); 
          ICollection key = outdict.Keys; 
          DataRow newrow = dataTable.NewRow(); 
          foreach (string k_loopVariable in key) 
          { 
           CommonModule.LogTheMessage(outdict[k_loopVariable],"","",""); 
           newrow[k_loopVariable] = outdict[k_loopVariable]; 
          } 
          dataTable.Rows.Add(newrow); 
          CommonModule.LogTheMessage(dataTable.Rows.Count.ToString(), "", "row_count", ""); 
          outdict.Clear(); 
          keybufferbuilder.Length=0; 
          valuebufferbuilder.Length=0; 
          reading_value = false; 
          reading = false; 
          continue; 
         } 
        } 
        else 
        { 
         if (reading_value) 
         { 
          valuebufferbuilder.Append((char)s); 
          continue; 
         } 
         else 
         { 
          keybufferbuilder.Append((char)s); 
          continue; 
         } 
        } 
       } 
       else 
       { 
        switch ((char)s) 
        { 
         case ':': 
          reading_value = true; 
          break; 
         default: 
          if (reading_value) 
          { 
           valuebufferbuilder.Append((char)s); 
          } 
          else 
          { 
           keybufferbuilder.Append((char)s); 
          } 
          break; 
        } 
       } 
      } 
     } 

     return dataTable; 
    } 
} 
Powiązane problemy