从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(); //将用户列表序列化成JSON
string 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进行序列化和反序列化的工作原理,同时带大家了解了在前端电子表格中要想完全实现整个内容的数据序列化和反序列化应该如何做。

后续也会为大家带来更多有趣或者严肃的内容~

觉得不错,点个赞再走吧。

详解电子表格中的json数据:序列化与反序列化的更多相关文章

  1. C#中的Json的序列化和反序列化

    Json是一种通用的数据格式,我们在数据交换的时候,经常会用到,下面介绍c#中的json序列化和反序列化,当然也可用在asp.net,silverlight,wpf中.我们在下面实例讲解如何进行Jso ...

  2. 详解Google-ProtoBuf中结构化数据的编码

    本文的主要内容是google protobuf中序列化数据时用到的编码规则,但是,介绍具体的编码规则之前,我觉得有必要先简单介绍一下google protobuf.因此,本文首先会介绍一些google ...

  3. 在C#中,Json的序列化和反序列化的几种方式总结

    在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化Json数据到对象. 什么是JSON? JSON (JavaScript Object Notation) ...

  4. 在MVC中使用Json.Net序列化和反序列化Json对象

    在.Net的MVC开发中,经常会使用到Json对象,于是,系统提供了JsonResult这个对象,其本质是调用.Net系统自带的Json序列化类JavaScriptSerializer对数据对象进行序 ...

  5. 在C#中,Json的序列化和反序列化的几种方式总结 转载

    转载自  https://www.cnblogs.com/caofangsheng/p/5687994.html    谢谢 在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据 ...

  6. C#中,Json的序列化和反序列化的几种方式总结

    在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化Json数据到对象. 什么是JSON? JSON (JavaScript Object Notation) ...

  7. 在C#中,Json的序列化和反序列化的几种方式

    摘自:http://www.cnblogs.com/caofangsheng/p/5687994.html 在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化 ...

  8. 在C#中实现Json的序列化与反序列化

    第一种方式利用 JavaScriptSerializer [对应的Assembly 为 System.Web.Extensions.dll] 进行处理: public static class Kas ...

  9. 详解javaweb中jstl如何循环List中的Map数据_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 详解javaweb中jstl如何循环List中的Map数据 第一种方式: 1:后台代码(测试) List<Map& ...

随机推荐

  1. 解决联想R720双系统Ubuntu16.04的无线网卡开启问题及信号不稳定

    问题一:1.问题描述笔记本型号:Lenovo r720笔记本(i5-7300hq,gtx1060 maxq 6g),默认装入Win10系统,然而当装入Ubuntu16.04双系统时,会出现无线网卡(型 ...

  2. Filter防火墙

    实验简介 实验属于防火墙系列 实验目的 了解个人防火墙的基本工作原理: 掌握Filter防火墙的配置. 实验环境 一台安装了win7操作系统的主机. 预备知识 防火墙 防火墙(Firewall)是一项 ...

  3. Cartography Tools(制图工具)

    制图工具 1.制图优化 # Process: 分散标记 arcpy.DisperseMarkers_cartography("", "", "EXPA ...

  4. 2021MySQL 8.0.26安装教程,目前最新版(详细全面)

    MySQL 8 要比 MySQL 5.7 快 2 倍,还带来了大量的改进和更快的性能!所以为什么不用MySQL8呢!下面是MySQL 8.0.26的安装教程. 安装网址: https://dev.my ...

  5. spoj839 Optimal Marks(最小割,dinic)

    题目大意: 给你一个无向图\(G(V,E)\). 每个顶点都有一个int范围内的整数的标记. 不同的顶点可能有相同的标记. 对于边\((u,v)\),我们定义\(Cost(u,v)=mark [u]\ ...

  6. SudokuSolver 2.0:用C++实现的数独解题程序 【一】

    SudokuSolver 2.0 实现效果 H:\Read\num\Release>sudoku.exe Order please: Sudoku Solver 2.0 2021/10/2 by ...

  7. 高效动画实现原理-Jetpack Compose 初探索

    一.简介 Jetpack Compose是Google推出的用于构建原生界面的新Android 工具包,它可简化并加快 Android上的界面开发.Jetpack Compose是一个声明式的UI框架 ...

  8. java的加载与执行原理剖析

    到目前为止,我们接触过的重点术语,总结一下: Java体系的技术被划分为三大块: JavaSE:标准版 JavaEE:企业版 JavaME:微型版 安装JDK之后: JDK:java开发工具箱 JRE ...

  9. 【UE4 C++】Tick的三种方式、异步蓝图节点

    Tick的三种方式 包括 默认 Tick (Actor.Component.UMG) TimerManager 定时器 FTickableGameObject 可以写原生 Object 也可以继承UO ...

  10. series和读取外部数据

    1.为什么学习pandas 我们并不是不愿意学习新的知识,只是在学习之前我们更想知道学习他们能够帮助我们解决什么问题.--伟哥 numpy虽然能够帮助我们处理数值,但是pandas除了处理数值之外(基 ...