从XML到JSON
当下利用开发常见的B/S架构之下,咱们会遇到很多须要进行前后端数据传输的场景。而在这个传输的过程中,数据通过何种格局传输、形式是否迅速便捷、书写形式是否简略易学,都成为了程序员在开发时要考量的问题。
在1996年,W3C(World Wide Web Consortium,万维网联盟)正式颁布了XML1.0规范,
XML采纳规范格局为基于Web的利用提供了一个对立进行数据形容和数据交换的规范,不同于HTML侧重于解决":如何将文件显示在浏览器中",XML更加侧重于解决:"如何将数据以结构化形式形容"。
(须要留神的是,XML并不是一种编程语言,而是一种跨语言的数据格式。)
XML自身并不简单,然而加上W3C制订的DTD、XSD、XPath、XSLT等二十多个规范之后,这个简略的数据交换格局平白变得复杂了起来。程序员凡是遇到,只能头大。苦心孤诣钻研大半个月,也不好轻言本人全副分明了。
而此时,推动着技术后退的另一台蒸汽机也被点燃——Ajax技术开始风行,映衬出XML越来越不容忽视的毛病。XML得以实现是基于DOM树,而DOM在各种浏览器中的实现细节不尽相同,所以XML的跨浏览器兼容性并不好,这时须要一种新的数据负载格局集成到HTML页面中,以满足Ajax的要求。
终于,在XML诞生后的第八年——2002年,由Douglas Crockford开始应用JSON这种轻量级数据交换格局。
首条JSON信息收回后,最让人们诧异的是,这并不是一个全新的数据格式,它就是JavaScript。
document.domain = 'fudco';parent.session.receive( { to: "session", do: "test", text: "Hello world" } )
而因为这条数据内容自身就是JavaScript,因而不再须要做任何额定解析,应用JS编译器就能够解决所有。
因为JSON非常简单,很快就风靡Web世界,并且成为ECMA规范。简直所有编程语言都有解析JSON的库,而在JavaScript中,咱们能够间接应用JSON,因为JavaScript内置了JSON的解析。把JavaScript对象变成JSON,就是把这个对象序列化成一个JSON格局的字符串,这样才可能通过网络传递给其余计算机。如果咱们收到一个JSON格局的字符串,只须要把它反序列化成一个JavaScript对象,就能够在JavaScript中间接应用这个对象了。
Json的序列化和反序列化
正如一道菜做好后,须要装在盘子里端给顾客,前后端的数据传输也是如此。数据通过指定格局,将传输的对象序列化为二进制数据流,而后再通过反序列化将数据流内容转化成为对应的数据对象。
JSON中的数据模式与转化形式
在JSON中,数据有以下几种模式:
- 对象:一个没有程序的"键/值",格局如
- 数组:用以设置数值程序,格局如
- 字符串:任意数量的Unicode字符,格局如
进行数据序列化和反序列化的形式有以下三种:
- 应用JavaScriptSerializer类
- 应用DataContractJsonSerializer类
- 应用JSON.NET类库
以JavaScriptSerializer类为例,
//创立用户列表List<UserInfo> userList = new List<UserInfo>();userList.Add(new UserInfo() { ID = 1, Name = "张三", CreateTime = DateTime.Now });userList.Add(new UserInfo() { ID = 2, Name = "李四", CreateTime = DateTime.Now });userList.Add(new UserInfo() { ID = 2, Name = "王五" }); //创立一个JavaScriptSerializer对象JavaScriptSerializer serializer = new JavaScriptSerializer(); //将用户列表序列化成JSONstring serializedResult = serializer.Serialize(userList); //将JOSN反序列化成用户列表List<UserInfo> deserializeResult = serializer.Deserialize<List<UserInfo>>(serializedResult);
只须要调用对应办法,就能够间接实现对数据内容的序列化。
你认为到这里就完结了吗,当然没有。在理论利用中,数据自身的解决并没有什么难度,真正须要思考解决的问题是,数据自身附加的属性、设置。就以咱们本身为例,客户在纯前端电子表格中对JSON数据传输的实在需要是,这段数据须要保障所有可视化内容的残缺传输。
纯前端表格中的JSON数据处理
在理论解决用户需要时,用户在设置好如下图单元格后,不仅仅是单元格内存在数字,还会遇到单元格自身的款式、自定义函数、 自定义格局、自定义函数迷你图、自定义标签,以及自定义行筛选。
咱们关上相干的代码,能够分明地看到在格局中这些对单元格的设置,都被保留了下来。
在这个图中,咱们能够看到不同类型的数据内容都能够实现序列化和反序列化的过程。在应用自定义序列化的过程中,查看相干代码,解决序列化的外围是typeName 字段在调用toJSON函数的过程,比方,能够将此类姓名和window对象分割。而反序列化时,调用 getTypeFromString 函数来获取类型名并且构造类型实例对象,而后调用类型实例上的 fromJSON办法。
此外还有许多其余的属性内容,上面列举其余款式设置的例子:
背景图片:
//这个例子设置了backgroundImageLayout属性。var style = new GC.Spread.Sheets.Style();style.backColor = "lightgreen";style.backgroundImage = "/css/images/quarter1.png";style.backgroundImageLayout = GC.Spread.Sheets.ImageLayout.center;activeSheet.setStyle(1,1,style,GC.Spread.Sheets.SheetArea.viewport);
水印设置:
//此示例设置水印的单元格填充。var type = new GC.Spread.Sheets.Style();type.watermark = "User name";type.cellPadding = "20";type.labelOptions = {alignment:GC.Spread.Sheets.LabelAlignment.topLeft, visibility: GC.Spread.Sheets.LabelVisibility.visible};activeSheet.setStyle(0, 1, type);activeSheet.getRange(0, -1, 1, -1, GC.Spread.Sheets.SheetArea.viewport).height(60);activeSheet.getRange(-1, 1, -1, 1).width(150);var combo = new GC.Spread.Sheets.CellTypes.ComboBox();combo.items([{ text: "Oranges", value: "11k" }, { text: "Apples", value: "15k" }, { text: "Grape", value: "100k" }]);combo.editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.text);activeSheet.setCellType(2, 1, combo, GC.Spread.Sheets.SheetArea.viewport);activeSheet.getCell(2, 1, GC.Spread.Sheets.SheetArea.viewport).watermark("ComboBox Cell Type").cellPadding('10 10 20 10');activeSheet.getCell(2, 1, GC.Spread.Sheets.SheetArea.viewport).labelOptions({alignment: GC.Spread.Sheets.LabelAlignment.bottomCenter, foreColor: 'yellowgreen', font: 'bold 15px Arial'});activeSheet.getRange(2, -1, 1, -1, GC.Spread.Sheets.SheetArea.viewport).height(60);
主题字体:
//这个例子应用了themeFont属性。var style = new GC.Spread.Sheets.Style();style.formatter = "0.000%";style.themeFont = "Body";activeSheet.setStyle(1,1,style,GC.Spread.Sheets.SheetArea.viewport);activeSheet.getCell(1,1).value("11");
还有许多对于单元格的设置,这些款式内容都能够被残缺保留下来,作为json数据进行传输,带来真正的表格json数据传输的便当。
应用过程中须要留神以下问题:
- 给 typeName 字段设置残缺的类型名字符串(如果有命名空间也应蕴含命名空间)。
- 如果自定义类型有循环依赖或是你心愿减小JSON 数据的大小,亦或是你有其余更高级的需要,那么你的自定义类型须要重写toJSON和fromJSON办法。
- 如果自定义类型定义在一个闭包中,换句话说,你不心愿将自定义类型定义在 window 对象上,你须要重写 getTypeFromString 函数来手动解析类型的字符串。
代码示例:
GC.Spread.Sheets.getTypeFromString = function(typeString) { switch (typeString) { case "MyFormatter": return MyFormatter; case "MyRowFilter": return MyRowFilter; default: return oldFun.apply(this, arguments); } };MyTag.prototype.toJSON = function() { return { typeName: this.typeName, //necessary name: this.name, age: this.age };};MyTag.prototype.fromJSON = function(settings) { if (settings.name !== undefined) { this.name = settings.name; } if (settings.age !== undefined) { this.age = settings.age; }};
总结
本文具体为大家介绍了数据传输从XML到JSON的故事,以及json进行序列化和反序列化的工作原理,同时带大家理解了在前端电子表格中要想齐全实现整个内容的数据序列化和反序列化应该如何做。
后续也会为大家带来更多乏味或者庄重的内容~
感觉不错,点个赞再走吧。
扩大浏览
- SpreadJS 产品官网
- Spread JSON 导入/导出