JSON資料整理
1.什麼是JSON
JSON(JavaScript Object Notation) 是一種輕量級的資料交換格式。它基於JavaScript的一個子集。 JSON採用完全獨立於語言的文字格式,但是也使用了類似於C語言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。這些特性使JSON成為理想的資料交換語言。易於人閱讀和編寫,同時也易於機器解析和生成。
2.JSON語法規則
JSON 語法是 JavaScript 物件表示法語法的子集。
l 資料在名稱/值對中
l 資料由逗號分隔
l 花括號儲存物件
l 方括號儲存陣列
JSON 資料的書寫格式是:名稱/值對。
名稱/值對包括欄位名稱(在雙引號中),後面寫一個冒號,然後是值:
"firstName" : "John"
這很容易理解,等價於這條 JavaScript 語句:
firstName = "John"
JSON 值可以是:
l 數字(整數或浮點數)
l 字串(在雙引號中)
l 邏輯值(true 或 false)
l 陣列(在方括號中)
l 物件(在花括號中)
l null
JSON線上校驗格式化工具:bejson
3.JSON基礎結構
JSON建構有兩種結構
JSON簡單說就是javascript中的物件和陣列,所以這兩種結構就是物件和陣列兩種結構,通過這兩種結構可以表示各種複雜的結構。
1、物件:物件在js中表示為“{}”括起來的內容,資料結構為 {key:value,key:value,...}的鍵值對的結構,在物件導向的語言中,key為物件的屬性,value為對應的屬性值,所以很容易理解,取值方法為 物件.key 獲取屬性值,這個屬性值的型別可以是 數字、字串、陣列、物件幾種。
2、陣列:陣列在js中是中括號“[]”括起來的內容,資料結構為 ["java","javascript","vb",...],取值方式和所有語言中一樣,使用索引獲取,欄位值的型別可以是 數字、字串、陣列、物件幾種。
經過物件、陣列2種結構就可以組合成複雜的資料結構了。
4.JSON基礎示例
簡單地說,JSON 可以將 JavaScript 物件中表示的一組資料轉換為字串,然後就可以在函式之間輕鬆地傳遞這個字串,或者在非同步應用程式中將字串從 Web 客戶機傳遞給伺服器端程式。這個字串看起來有點兒古怪,但是JavaScript很容易解釋它,而且 JSON 可以表示比"名稱 / 值對"更復雜的結構。例如,可以表示陣列和複雜的物件,而不僅僅是鍵和值的簡單列表。
名稱 / 值對
按照最簡單的形式,可以用下面這樣的 JSON 表示"名稱 / 值對":
{ "firstName": "Brett" }
這個示例非常基本,而且實際上比等效的純文字"名稱 / 值對"佔用更多的空間:
firstName=Brett
但是,當將多個"名稱 / 值對"串在一起時,JSON 就會體現出它的價值了。首先,可以建立包含多個"名稱 / 值對"的 記錄,比如:
{ "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" }
從語法方面來看,這與"名稱 / 值對"相比並沒有很大的優勢,但是在這種情況下 JSON 更容易使用,而且可讀性更好。例如,它明確地表示以上三個值都是同一記錄的一部分;花括號使這些值有了某種聯絡。
表示陣列
當需要表示一組值時,JSON 不但能夠提高可讀性,而且可以減少複雜性。例如,假設您希望表示一個人名列表。在XML中,需要許多開始標記和結束標記;如果使用典型的名稱 / 值對(就像在本系列前面文章中看到的那種名稱 / 值對),那麼必須建立一種專有的資料格式,或者將鍵名稱修改為 person1-firstName這樣的形式。
如果使用 JSON,就只需將多個帶花括號的記錄分組在一起:
{ "people": [ { "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" }, { "firstName": "Jason", "lastName":"Hunter", "email": "bbbb"}, { "firstName": "Elliotte", "lastName":"Harold", "email": "cccc" } ] }
這不難理解。在這個示例中,只有一個名為 people的變數,值是包含三個條目的陣列,每個條目是一個人的記錄,其中包含名、姓和電子郵件地址。上面的示例演示如何用括號將記錄組合成一個值。當然,可以使用相同的語法表示多個值(每個值包含多個記錄):
{ "programmers": [ { "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" }, { "firstName": "Jason", "lastName":"Hunter", "email": "bbbb" }, { "firstName": "Elliotte", "lastName":"Harold", "email": "cccc" } ], "authors": [ { "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" }, { "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" }, { "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" } ], "musicians": [ { "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" }, { "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" } ] }
這裡最值得注意的是,能夠表示多個值,每個值進而包含多個值。但是還應該注意,在不同的主條目(programmers、authors 和 musicians)之間,記錄中實際的名稱 / 值對可以不一樣。JSON 是完全動態的,允許在 JSON 結構的中間改變表示資料的方式。
在處理 JSON 格式的資料時,沒有需要遵守的預定義的約束。所以,在同樣的資料結構中,可以改變表示資料的方式,甚至可以以不同方式表示同一事物。
5.JSON和XML比較
可讀性
JSON和XML的可讀性可謂不相上下,一邊是簡易的語法,一邊是規範的標籤形式,很難分出勝負。
可擴充套件性
XML天生有很好的擴充套件性,JSON當然也有,沒有什麼是XML能擴充套件,而JSON卻不能擴充套件的。不過JSON在Javascript主場作戰,可以儲存Javascript複合物件,有著xml不可比擬的優勢。
編碼難度、解碼難度(略)
例項比較
XML和JSON都使用結構化方法來標記資料,下面來做一個簡單的比較。
用XML表示中國部分省市資料如下:
<?xml version="1.0" encoding="utf-8"?> <country> <name>中國</name> <province> <name>黑龍江</name> <cities> <city>哈爾濱</city> <city>大慶</city> </cities> </province> <province> <name>廣東</name> <cities> <city>廣州</city> <city>深圳</city> <city>珠海</city> </cities> </province> <province> <name>臺灣</name> <cities> <city>臺北</city> <city>高雄</city> </cities> </province> <province> <name>新疆</name> <cities> <city>烏魯木齊</city> </cities> </province> </country>
用JSON表示如下:
{ "name":"中國", "province":[ { "name":"黑龍江", "cities":{ "city":["哈爾濱","大慶"] } }, { "name":"廣東", "cities":{ "city":["廣州","深圳","珠海"] } }, { "name":"臺灣", "cities":{ "city":["臺北","高雄"] } }, { "name":"新疆", "cities":{ "city":["烏魯木齊"] } } ] }
6. .NET操作JSON
JSON檔案讀入到記憶體中就是字串,.NET操作JSON就是生成與解析JSON字串。操作JSON通常有以下幾種方式:
1. 原始方式:自己按照JSON的語法格式,寫程式碼直接操作JSON字串。如非必要,應該很少人會走這條路,從頭再來的。
2. 通用方式:這種方式是使用開源的類庫Newtonsoft.Json(下載地址http://json.codeplex.com/)。下載後加入工程就能用。通常可以使用JObject, JsonReader, JsonWriter處理。這種方式最通用,也最靈活,可以隨時修改不爽的地方。
(1)使用JsonReader讀Json字串:
string jsonText = @"{""input"" : ""value"", ""output"" : ""result""}"; JsonReader reader = new JsonTextReader(new StringReader(jsonText)); while (reader.Read()) { Console.WriteLine(reader.TokenType + "\t\t" + reader.ValueType + "\t\t" + reader.Value); }
(2)使用JsonWriter寫字串:
StringWriter sw = new StringWriter(); JsonWriter writer = new JsonTextWriter(sw); writer.WriteStartObject(); writer.WritePropertyName("input"); writer.WriteValue("value"); writer.WritePropertyName("output"); writer.WriteValue("result"); writer.WriteEndObject(); writer.Flush(); string jsonText = sw.GetStringBuilder().ToString(); Console.WriteLine(jsonText);
(3)使用JObject讀寫字串:
JObject jo = JObject.Parse(jsonText); string[] values = jo.Properties().Select(item => item.Value.ToString()).ToArray();
(4)使用JsonSerializer讀寫物件(基於JsonWriter與JsonReader):
Project p = new Project() { Input = "stone", Output = "gold" }; JsonSerializer serializer = new JsonSerializer(); StringWriter sw = new StringWriter(); serializer.Serialize(new JsonTextWriter(sw), p); Console.WriteLine(sw.GetStringBuilder().ToString()); StringReader sr = new StringReader(@"{""Input"":""stone"", ""Output"":""gold""}"); Project p1 = (Project)serializer.Deserialize(new JsonTextReader(sr), typeof(Project)); Console.WriteLine(p1.Input + "=>" + p1.Output);
上面的程式碼都是基於下面這個Project類定義:
class Project { public string Input { get; set; } public string Output { get; set; } }
此外,如果上面的JsonTextReader等類編譯不過的話,說明是我們自己修改過的類,換成你們自己的相關類就可以了,不影響使用。
3. 內建方式:使用.NET Framework 3.5/4.0中提供的System.Web.Script.Serialization名稱空間下的JavaScriptSerializer類進行物件的序列化與反序列化,很直接。
Project p = new Project() { Input = "stone", Output = "gold" }; JavaScriptSerializer serializer = new JavaScriptSerializer(); var json = serializer.Serialize(p); Console.WriteLine(json); var p1 = serializer.Deserialize<Project>(json); Console.WriteLine(p1.Input + "=>" + p1.Output); Console.WriteLine(ReferenceEquals(p,p1));
注意:如果使用的是VS2010,則要求當前的工程的Target Framework要改成.Net Framework 4,不能使用Client Profile。當然這個System.Web.Extensions.dll主要是Web使用的,直接在Console工程中用感覺有點浪費資源。
此外,從最後一句也可以看到,序列化與反序列化是深拷貝的一種典型的實現方式。
更新1:
注意用System.Web.Script.Serialization的時候,序列化沒問題,反序列化會將DateTime賦值成了UTC時間。
UTC時間 + 時區差 = 本地時間
6:02 + (+0800) = 14:02(北京時間)
DateTime dt = DateTime.Now; JavaScriptSerializer serializer = new JavaScriptSerializer(); var json = serializer.Serialize(dt); Console.WriteLine(json); var dt1 = serializer.Deserialize<DateTime>(json); Response.Write(dt1.ToString()+"<br />"); Response.Write(ReferenceEquals(dt, dt1));
關於UTC時間與北京時間的區別請移步:UTC時間與北京時間差多久?
4. 契約方式:使用System.Runtime.Serialization.dll提供的DataContractJsonSerializer或者 JsonReaderWriterFactory實現。
Project p = new Project() { Input = "stone", Output = "gold" }; DataContractJsonSerializer serializer = new DataContractJsonSerializer(p.GetType()); string jsonText; using (MemoryStream stream = new MemoryStream()) { serializer.WriteObject(stream, p); jsonText = Encoding.UTF8.GetString(stream.ToArray()); Console.WriteLine(jsonText); } using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonText))) { DataContractJsonSerializer serializer1 = new DataContractJsonSerializer(typeof(Project)); Project p1 = (Project)serializer1.ReadObject(ms); Console.WriteLine(p1.Input + "=>" + p1.Output); }
這裡要注意,這裡的Project類和成員要加相關的Attribute:
[DataContract] class Project { [DataMember] public string Input { get; set; } [DataMember] public string Output { get; set; } }
實用參考:
JSON驗證工具:http://jsonlint.com/
JSON簡明教程:http://www.w3school.com.cn/json/
Newtonsoft.Json類庫下載:http://json.codeplex.com/
通過序列化將.net物件轉換為JSON字串
在web開發過程中,我們經常需要將從資料庫中查詢到的資料(一般為一個集合,列表或陣列等)轉換為JSON格式字串傳回客戶端,這就需要進行序列化,這裡用到的是JsonConvert物件的SerializeObject方法。其語法格式為:JsonConvert.SerializeObject(object),程式碼中的”object”就是要序列化的.net物件,序列化後返回的是json字串。
比如,現在我們有一個TStudent的學生表,表中的欄位和已有資料如圖所示
從表中我們可以看到一共有五條資料,現在我們要從資料庫中取出這些資料,然後利用JSON.NET的JsonConvert物件序列化它們為json字串,並顯示在頁面上。C#程式碼如下
protected void Page_Load(object sender, EventArgs e) { using (L2SDBDataContext db = new L2SDBDataContext()) { List<Student> studentList = new List<Student>(); var query = from s in db.TStudents select new { StudentID=s.StudentID, Name=s.Name, Hometown=s.Hometown, Gender=s.Gender, Brithday=s.Birthday, ClassID=s.ClassID, Weight=s.Weight, Height=s.Height, Desc=s.Desc }; foreach (var item in query) { Student student = new Student { StudentID=item.StudentID,Name=item.Name,Hometown=item.Hometown,Gender=item.Gender,Brithday=item.Brithday,ClassID=item.ClassID,Weight=item.Weight,Height=item.Height,Desc=item.Desc}; studentList.Add(student); } lbMsg.InnerText = JsonConvert.SerializeObject(studentList); } }
輸出結果:
從圖中我們可以看到,資料庫中的5條記錄全部取出來並轉化為json字串了。
使用LINQ to JSON定製JSON資料
使用JsonConvert物件的SerializeObject只是簡單地將一個list或集合轉換為json字串。但是,有的時候我們的前端框架比如ExtJs對服務端返回的資料格式是有一定要求的,比如下面的資料格式,這時就需要用到JSON.NET的LINQ to JSON,LINQ to JSON的作用就是根據需要的格式來定製json資料。
比如經常用在分頁的json格式如程式碼:
{ "total": 5, //記錄總數 "rows":[ //json格式的資料列表 ] }
使用LINQ to JSON前,需要引用Newtonsoft.Json的dll和using Newtonsoft.Json.Linq的名稱空間。LINQ to JSON主要使用到JObject, JArray, JProperty和JValue這四個物件,JObject用來生成一個JSON物件,簡單來說就是生成”{}”,JArray用來生成一個JSON陣列,也就是”[]”,JProperty用來生成一個JSON資料,格式為key/value的值,而JValue則直接生成一個JSON值。下面我們就用LINQ to JSON返回上面分頁格式的資料。程式碼如下:
protected void Page_Load(object sender, EventArgs e) { using (L2SDBDataContext db = new L2SDBDataContext()) { //從資料庫中取出資料並放到列表list中 List<Student> studentList = new List<Student>(); var query = from s in db.TStudents select new { StudentID = s.StudentID, Name = s.Name, Hometown = s.Hometown, Gender = s.Gender, Brithday = s.Birthday, ClassID = s.ClassID, Weight = s.Weight, Height = s.Height, Desc = s.Desc }; foreach (var item in query) { Student student = new Student { StudentID = item.StudentID, Name = item.Name, Hometown = item.Hometown, Gender = item.Gender, Brithday = item.Brithday, ClassID = item.ClassID, Weight = item.Weight, Height = item.Height, Desc = item.Desc }; studentList.Add(student); } //基於建立的list使用LINQ to JSON建立期望格式的JSON資料 lbMsg.InnerText = new JObject( new JProperty("total",studentList.Count), new JProperty("rows", new JArray( //使用LINQ to JSON可直接在select語句中生成JSON資料物件,無須其它轉換過程 from p in studentList select new JObject( new JProperty("studentID",p.StudentID), new JProperty("name",p.Name), new JProperty("homeTown",p.Hometown) ) ) ) ).ToString(); } }
輸出結果為:
處理客戶端提交的JSON資料
客戶端提交過來的資料一般都是json字串,有了更好地進行操作(物件導向的方式),所以我們一般都會想辦法將json字串轉換為json物件。例如客戶端提交了以下陣列格式json字串。
[ {StudentID:"100",Name:"aaa",Hometown:"china"}, {StudentID:"101",Name:"bbb",Hometown:"us"}, {StudentID:"102",Name:"ccc",Hometown:"england"} ]
在服務端就可以使用JObject或JArray的Parse方法輕鬆地將json字串轉換為json物件,然後通過物件的方式提取資料。下面是服務端程式碼。
protected void Page_Load(object sender, EventArgs e) { string inputJsonString = @" [ {StudentID:'100',Name:'aaa',Hometown:'china'}, {StudentID:'101',Name:'bbb',Hometown:'us'}, {StudentID:'102',Name:'ccc',Hometown:'england'} ]"; JArray jsonObj = JArray.Parse(inputJsonString); string message = @"<table border='1'> <tr><td width='80'>StudentID</td><td width='100'>Name</td><td width='100'>Hometown</td></tr>"; string tpl = "<tr><td>{0}</td><td>{1}</td><td>{2}</td></tr>"; foreach (JObject jObject in jsonObj) { message += String.Format(tpl, jObject["StudentID"], jObject["Name"],jObject["Hometown"]); } message += "</table>"; lbMsg.InnerHtml = message; }
輸出結果:
當然,服務端除了使用LINQ to JSON來轉換json字串外,也可以使用JsonConvert的DeserializeObject方法。如下面程式碼實現上面同樣的功能。
List<Student> studentList = JsonConvert.DeserializeObject<List<Student>>(inputJsonString);//注意這裡必須為List<Student>型別,因為客戶端提交的是一個陣列json foreach (Student student in studentList) { message += String.Format(tpl, student.StudentID, student.Name,student.Hometown); }
總結:
在客戶端,讀寫json物件可以使用”.”操作符或”["key”]”,json字串轉換為json物件使用eval()函式。
在服務端,由.net物件轉換json字串優先使用JsonConvert物件的SerializeObject方法,定製輸出json字串使用LINQ to JSON。由json字串轉換為.net物件優先使用JsonConvert物件的DeserializeObject方法,然後也可以使用LINQ to JSON。
相關文章
- JSON資料JSON
- 資料庫資料整理資料庫
- Map 轉json資料,json資料轉換為MapJSON
- 資料庫整理資料庫
- json資料解析JSON
- JSON 資料格式JSON
- 專案資料整理
- docker 文件資料整理Docker
- HSQLDB資料庫整理SQL資料庫
- BigCouch資料整理GC
- LOCK的整理資料
- Go之json資料GoJSON
- 解析大資料json大資料JSON
- 讀取JSON資料JSON
- 處理JSON資料JSON
- jmeter 取json資料JMeterJSON
- json資料介紹JSON
- [C#] CHO.Json操作Json資料C#JSON
- 🎩 JSON Wizard for Mac - 解析你的 JSON 資料!🔮JSONMac
- flutter json資料處理FlutterJSON
- jQuery、ajax新增Json資料jQueryJSON
- Hive處理Json資料HiveJSON
- SpringMVC接受JSON資料SpringMVCJSON
- .net 對JSON資料排序JSON排序
- JSON資料格式的使用JSON
- C# 生成Json資料C#JSON
- 讓Solr返回JSON資料SolrJSON
- php操作JSON格式資料PHPJSON
- lazarus資料序列為JSONJSON
- MySQL之json資料操作MySqlJSON
- 資料集轉換JSONJSON
- Go 學習資料整理Go
- Oracle資料表碎片整理Oracle
- 【java基礎資料整理】Java
- 資料庫事務整理資料庫
- ArcGIS參考資料整理
- iOS 學習資料整理iOS
- 整理月平均效能資料