2011-06-05 83 views
32

我在C#中有一個像下面的字符串。我需要循環並創建一個HTML表格輸出。我嘗試使用JSON.NET,但無法弄清楚如何檢索密鑰(名稱,年齡&作業)。使用JSON.NET解析json字符串

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

表格式

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

任何幫助將不勝感激。


由Dave提供的代碼是這裏的理想解決方案..但它對於.NET 4.0的工作。我已經使用JSON.NET下面的代碼使用Newtonsoft.Json .NET 3.5

。 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

這不是JSON。 http://jsonlint.com/將幫助您找到錯誤。 – Quentin 2011-06-06 16:28:23

回答

29

您可以使用.NET 4的動態類型和內置JavaScriptSerializer來做到這一點。事情是這樣的,也許:

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(); 

最後,myTable將舉行一個字符串,它看起來像這樣:

<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

很好地完成了,使用動態而不是DataTable會產生性能開銷嗎?我仍然使用.NET 3.5所以我在實踐中沒有使用過多的動態效果 – Frank 2011-06-06 18:49:43

+1

@Frank Dynamics確實帶來了額外的開銷,但並沒有那麼糟糕。在Core i7的LINQPad上運行代碼平均9ms以上。 – 2011-06-06 22:08:35

+0

@Dave ..非常感謝代碼snipplet ..但不幸的是我的項目是.NET 3.5,並不能使用你的解決方案..我想出了一個使用JSON.NET的解決方案..如果任何人需要.NET 3.5解決方案,我已經發布了上面的示例代碼.. – 2011-06-07 07:06:58

2

我沒有測試下面的代碼片段......希望它會爲您指出正確的方向:

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

嗨,謝謝你的回覆..我的問題其實是鑰匙(名稱,年齡和工作)不固定..它可以變化..所以我需要從JSON字符串檢索鑰匙...是無論如何要動態獲取它? – 2011-06-06 05:56:51

2

如果你的鍵是動態的,我建議直接反序列化到一個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  
    } 

一旦反序列化,就可以動態確定DataTable列的名稱和類型。

+1

上述解決方案適用於4.0版本以前的.NET版本。戴夫提出的動態版本也很好。 – Frank 2011-06-06 18:45:57

+0

此解決方案還需要預定義的JSON密鑰(名稱,年齡等)! – 2011-06-07 07:55:24

+2

@Anz列名不需要預定義。當DataTable被反序列化時,它們被推斷出來。請參閱上面的更新,演示如何在不明確知道列名的情況下打印表。 – Frank 2011-06-07 14:26:52