从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. 03 依赖注入--01控制反转、IoC模式

    控制反转Inversion of Control DI和IoC几乎都是成对出现的,我们在理解依赖注入之前首先要弄明白什么是IoC,也就是控制反转,体现的就是控制权的转移,即控制权原来在A中,现在需要B ...

  2. Hutool时间和日期相关工具

    日期时间工具 获取当前时间(1) public class HDateAndTime { public static void main(String[] args) { //获取当前时间 Date ...

  3. MySQL MVCC原理深入探索

    一.MVCC的由来 二.MVCC的实际应用 RR级别场景 RC级别场景 三.MVCC的实现 3.1 多版本的数据从哪里来--Undo Log 3.1.1 插入操作对应的undo log 3.1.2 删 ...

  4. 四种引用类型在Springboot中的使用

    今天 4ye 来和小伙伴们聊聊这个 强引用,软引用,弱引用,幻象引用(虚引用)啦 嘿嘿,主要是最近读源码的时候经常看到,然后又想到自己第一次知道这个神奇的东西是在 2020-8-21 为啥记得这么清楚 ...

  5. 洛谷4719 【模板】动态dp 学习笔记(ddp 动态dp)

    qwq大概是混乱的一个题. 首先,还是从一个比较基础的想法开始想起. 如果每次暴力修改的话,那么每次就可以暴力树形dp 令\(dp[x][0/1]\)表示\(x\)的子树中,是否选择\(x\)这个点的 ...

  6. Android QMUI实战:实现APP换肤功能,并自动适配手机深色模式

    Android换肤功能已不是什么新鲜事了,市面上有很多第三方的换肤库和实现方案. 之所以选择腾讯的QMUI库来演示APP的换肤功能,主要原因: 1.换肤功能的实现过程较简单.容易理解: 2.能轻松适配 ...

  7. 虚拟机研究系列-「GC本质底层机制」SafePoint的深入分析和底层原理探究指南

    SafePoint前提介绍 在高度优化的现代JVM里,Safepoint有几种不同的用法.GC safepoint是最常见.大家听说得最多的,但还有deoptimization safepoint也很 ...

  8. python常用功能

    1. 获取昨天日期 引入datetime模块 import datetime def getYesterday(): today = datetime.date.today() #返回当前本地日期 # ...

  9. 【c++ Prime 学习笔记】第4章 表达式

    表达式由一个或多个运算对象组成,对表达式求值返回结果. 字面值和变量是最简单的表达式 把运算符和运算对象组合可得到复杂表达式. 4.1 基础 4.1.1 基本概念 一元运算符作用于一个对象,如取地址符 ...

  10. Scrum Meeting 0531

    零.说明 日期:2021-5-31 任务:简要汇报两日内已完成任务,计划后两日完成任务 一.进度情况 组员 负责 两日内已完成的任务 后两日计划完成的任务 困难 qsy PM&前端 完成后端管 ...