2011-06-05 34 views
32

Tengo una cadena como la siguiente en C#. Necesito recorrer y crear una salida de tabla HTML. Intenté con JSON.NET pero no pude encontrar la forma de recuperar las claves (Nombre, Edad & Trabajo).Cadena Parse json usando JSON.NET

string data = "{items:[ 
{'Name':'AAA','Age':'22','Job':'PPP'} 
,{'Name':'BBB','Age':'25','Job':'QQQ'} 
,{'Name':'CCC','Age':'38','Job':'RRR'}]}"; 

El formato de tabla es

 
......................... 
| Name | Age | Job | 
......................... 
| AAA | 22 | PPP | 
......................... 
| BBBB | 25 | QQQ | 
......................... 
| CCC | 28 | RRR | 
......................... 

Cualquier ayuda será muy apreciada.


El código proporcionado por Dave es la solución ideal aquí .. pero que funcione para .NET 4.0 .. He utilizado con el siguiente código para .NET 3.5 JSON.NET

usando Newtonsoft.Json. Linq;

string jsonString = "{items:[{'Name':'Anz','Age':'29','Job':''},{'Name':'Sanjai','Age':'28','Job':'Developer'},{'Name':'Rajeev','Age':'31','Job':'Designer'}]}"; 

     JObject root = JObject.Parse(jsonString); 

     JArray items = (JArray)root["items"]; 

     JObject item; 
     JToken jtoken; 

     for (int i = 0; i < items.Count; i++) //loop through rows 
     { 
      item = (JObject)items[i]; 
      jtoken = item.First; 

      while (jtoken != null)//loop through columns 
      { 
       Response.Write(((JProperty)jtoken).Name.ToString() + " : " + ((JProperty)jtoken).Value.ToString() + "<br />"); 

       jtoken = jtoken.Next; 
      } 
     } 
+2

Eso no es JSON. http://jsonlint.com/ te ayudará a encontrar errores. – Quentin

Respuesta

29

Puede usar el tipo dinámico de .NET 4 y el JavaScriptSerializer incorporado para hacer eso. Algo como esto, tal vez:

string json = "{\"items\":[{\"Name\":\"AAA\",\"Age\":\"22\",\"Job\":\"PPP\"},{\"Name\":\"BBB\",\"Age\":\"25\",\"Job\":\"QQQ\"},{\"Name\":\"CCC\",\"Age\":\"38\",\"Job\":\"RRR\"}]}"; 

var jss = new JavaScriptSerializer(); 

dynamic data = jss.Deserialize<dynamic>(json); 

StringBuilder sb = new StringBuilder(); 

sb.Append("<table>\n <thead>\n <tr>\n"); 

// Build the header based on the keys in the 
// first data item. 
foreach (string key in data["items"][0].Keys) { 
     sb.AppendFormat("  <th>{0}</th>\n", key); 
} 

sb.Append(" </tr>\n </thead>\n <tbody>\n"); 

foreach (Dictionary<string, object> item in data["items"]) { 
    sb.Append(" <tr>\n"); 

    foreach (string val in item.Values) { 
     sb.AppendFormat("  <td>{0}</td>\n", val); 
    } 
} 

sb.Append(" </tr>\n </tbody>\n</table>"); 

string myTable = sb.ToString(); 

Al final, myTable llevará a cabo una cadena que se ve así:

<table> 
    <thead> 
     <tr> 
      <th>Name</th> 
      <th>Age</th> 
      <th>Job</th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr> 
      <td>AAA</td> 
      <td>22</td> 
      <td>PPP</td> 
     <tr> 
      <td>BBB</td> 
      <td>25</td> 
      <td>QQQ</td> 
     <tr> 
      <td>CCC</td> 
      <td>38</td> 
      <td>RRR</td> 
     </tr> 
    </tbody> 
</table> 
+0

Bien hecho. ¿Hay una sobrecarga de rendimiento asociada con el uso dinámico en comparación con una DataTable? Todavía estoy usando .NET 3.5 así que no he usado mucho en la práctica dinámica. – Frank

+1

@Frank Dynamics tiene una carga adicional, pero no es tan malo. Ejecutar el código anterior promedia 9 ms en LINQPad en mi Core i7. –

+0

@Dave ... muchas gracias por el código snipplet ... pero desafortunadamente mi proyecto es .NET 3.5 y no pude usar su solución ... Descubrí una solución usando JSON.NET para esto ... si alguien más necesita la solución .NET 3.5, he publicado el código de muestra anterior ... –

2

no he probado el siguiente fragmento ... espero que te orientará en la dirección correcta:

var jsreader = new JsonTextReader(new StringReader(stringData)); 
    var json = (JObject)new JsonSerializer().Deserialize(jsreader); 
    var tableRows = from p in json["items"] 
       select new 
       { 
        Name = (string)p["Name"], 
        Age = (int)p["Age"], 
        Job = (string)p["Job"] 
       }; 
+1

Hola, gracias por la respuesta ... mi problema es que las claves (nombre, edad y trabajo) no están corregidas ... pueden variar ... así que también necesito recuperar las claves de la cadena json ... ¿hay alguna? de todos modos para obtenerlo de forma dinámica? –

2

Si sus teclas son dinámicos sugeriría deserializar directamente en un DataTable:

class SampleData 
    { 
     [JsonProperty(PropertyName = "items")] 
     public System.Data.DataTable Items { get; set; } 
    } 

    public void DerializeTable() 
    { 
     const string json = @"{items:[" 
      + @"{""Name"":""AAA"",""Age"":""22"",""Job"":""PPP""}," 
      + @"{""Name"":""BBB"",""Age"":""25"",""Job"":""QQQ""}," 
      + @"{""Name"":""CCC"",""Age"":""38"",""Job"":""RRR""}]}"; 
     var sampleData = JsonConvert.DeserializeObject<SampleData>(json); 
     var table = sampleData.Items; 

     // write tab delimited table without knowing column names 
     var line = string.Empty; 
     foreach (DataColumn column in table.Columns)    
      line += column.ColumnName + "\t";      
     Console.WriteLine(line); 

     foreach (DataRow row in table.Rows) 
     { 
      line = string.Empty; 
      foreach (DataColumn column in table.Columns)     
       line += row[column] + "\t";         
      Console.WriteLine(line); 
     } 

     // Name Age Job  
     // AAA 22 PPP  
     // BBB 25 QQQ  
     // CCC 38 RRR  
    } 

Puede determinar los nombres y tipos de columna DataTable dinámicamente una vez deserializados.

+1

La solución anterior funciona para versiones .NET anteriores a la 4.0. La versión dinámica propuesta por Dave también es agradable. – Frank

+0

¡Esta solución también necesita las teclas JSON (Nombre, Edad, etc.) predefinidas! –

+2

@Anz Los nombres de las columnas no necesitan ser predefinidos. Se deducen cuando se deserializa la DataTable. Consulte mi actualización anterior que demuestra cómo imprimir la tabla sin conocer explícitamente los nombres de las columnas. – Frank