Reprinted From CNBlogs QiaoGaojian ,JianShu XiguaJuziPotaoIce ShuangQimu:
1.什么是Json
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。
JSON是基于文本的数据格式,JSON在传递的时候是传递符合JSON这种格式的字符串,我们常称为“JSON字符串”。
2.JSON 语法规则
- 数据在键值对中
- 数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
Json数据的书写格式是:键/值
"name" : "zhangsan"
Json的键使用字符串表示
Json的值可以是:
- 数值(整数或浮点数)
- 字符串
- 布尔值(true或false)
- 数组(在中括号中)
- 对象(在大括号中)
- 空(null)
数据直接用逗号隔开
大括号保存数据
Json的两种结构,对象和数组
对象使用大括号保存数据
{"name" : "ZhangSan", "ID" : 123456}
数组使用中括号保存数据
{ "Player" : [ {"name" : "ZhangSan", "ID" : 123456}, {"name" : "LiSi", "ID" : 123457}, {"name" : "WangWu", "ID" : 123458} ] }
3.Json的结构
- 对象:对象在js中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,...}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为 对象.key 获取属性值,这个属性值的类型可以是 数字、字符串、数组、对象几种。
- 数组:数组在js中是中括号“[]”括起来的内容,数据结构为 ["java","javascript","vb",...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是 数字、字符串、数组、对象几种。
4.Json在Unity3d中的使用
- 跟服务器进行数据交互
- 配置文件
- 跟Android/iOS数据交互
常用:
-
JsonUtility:JsonUtility是Untiy5.3后新增的内容,有时会出现莫名其妙的错误:
JsonUtility.FromJson():把json字符串转成对象.
JsonUtility.ToJson():把对象转成json字符串. -
LitJson:
LitJson是一个.NET平台下处理Json格式数据的类库。
LitJson是一个开源项目,比较小巧轻便,安装也很简单,在Unity里只需要把LitJson.dll放到Assets文件夹下,并在代码的最开头添加 “Using LitJson”命名空间就可以了。
LitJson Git地址
LitJson网站JsonMapper.ToObject():把json字符串转成对象.
JsonMapper.ToJson():把对象转成json字符串. -
hhttp://dl.pconline.com.cn/download/1017689.html
官网下载:http://www.json.org/json-zh.html---官网失效了打不开,我去的上面网址下载的 -
或者去github上下载源码—https://github.com/LitJSON/litjson,然后自己编一个.dll--可参考兰叶凛香文章;
-
放到Unity3d中的Plugin文件夹内
-
使用的话要注意引入命名空间
5.
代码举例 I:
转换
- 实例转换为JSON
public class Pet { public string name; public int age; string color; public void Bark () {/***/} } using LitJson; ... JsonMapper.ToJson(new Pet()); // => string: "{ 'name': null, 'age': 0 }"
PS: 实例方法和未公开的属性不会被转化
- 嵌套实例对象转换为JSON
public class PetColor { public int r; public int g; public int b; } public class Pet { public string name; public int age; public PetColor color; } var petA = new Pet(); petA.name = "Leokk"; petA.age = 12; petA.color = new PetColor(); JsonMapper.ToJson(petA); // => string: // "{'name':'Leokk', 'age':12, 'color': {'r':0, 'g':0, 'a':0}}"
- 常用类型转JSON
交错数组转JSON
var array = new string[][] { new string[]{ "bar", "foo" }, new string[]{ "baz" } }; JsonMapper.ToJson(array); // => string: "[["bar","foo"],["baz"]]"
二维数组转JSON
var array = new int[,] { { 1, 2, 3 }, { 55, 56, 57 } }; JsonMapper.ToJson(array); // => string: "[1, 2, 3, 55, 56, 57]" 列表转JSON
列表转JSON
var list = new List<bool>(new bool[]{ true, false }); JsonMapper.ToJson(list); // => string: "[true, false]"
4.JSON 字符串转为特定类的实例
class Pet { public string name; public int age; } var b = "{ 'name': 'Misha', 'age': 3 }"; var petB = JsonMapper.ToObject<Pet>(b); // => Pet: { name: "Misha", age: 3 }
为静态方法 JsonMapper.ToObject 指定泛型即可。注意属性要一一对应。
- 使用泛型将JSON 转为常用的类型
string arrayStr = "[1, 2, 3, 11, 12, 13]"; JsonMapper.ToObject<int[]>(arrayStr)[3]; // => int: 11 var arrayStr = "[['foo', 'baz'], ['bar']]"; var array = JsonMapper.ToObject<string[][]>(arrayStr); array[1][0]; // => string: "bar"
ps: 使用泛型时 ToObject
的参数只能为字符串形式,而不能以JsonData 类型的变量作为参数
不能将 List<int[]>
转换为交错数组
创建 JsonData 实例
- 创建字典型实例
var petC = new JsonData(); petC["name"] = "Huffer"; petC["age"] = 4; petC.ToJson(); // => string: "{ 'name': 'Huffer', 'age': 4 }"
JsonData jsondata1 = new JsonData(); jsondata1["name"] = "ZhangSan"; jsondata1["ID"] = 123456; jsondata1["sex"] = "male"; string json1 = jsondata1.ToJson(); print(json1); 运行结果:<font color=green>{"name":"ZhangSan","ID":123456,"sex":"male"}</font> JsonData jsondata2 = new JsonData(); jsondata2["name"] = "LiSi"; jsondata2["info"] = new JsonData(); jsondata2["info"]["ID"] = 123457; jsondata2["info"]["sex"] = "female"; string json2 = jsondata2.ToJson(); print(json2); 运行结果:<font color=green>{"name":"LiSi","info":{"ID":123457,"sex":"female"}}</font> 这里面使用了Jsondat中定义的 .ToJson方法
创建数组型实例,使用了实例方法Add
var rexxarsPets = new JsonData(); rexxarsPets.Add(petCA); rexxarsPets.Add(petCB); rexxarsPets.Add(petC); rexxarsPets.ToJson(); /* => string: "[ { 'name': 'Leokk', 'age': 2 }, { 'name': 'Misha', 'age': 3 }, { 'name': 'Huffer', 'age': 4 } ]" */
一旦将 JsonData 实例使用上述一种方式向内部添加元素之后,便不能再使用另一种方法进行添加了,即使使用下面的方法清空了实例也不行。
循环
- 使用属性
Count
配合for
关键字循环,可以用来循环像数组结构的 JsonData 实例。
string nameArrayString = "['Leokk', 'Misha']"; JsonData nameArray = JsonMapper.ToObject(nameArrayString); for (int i = 0; i < nameArray.Count; i++) { (string)nameArray[i]; } // "Leokk" // "Misha"
也可以用来循环正常的 JsonData 实例。
for (int i = 0; i < petA.Count; i++) { JsonData item = jsonDataA[i]; if (item.IsString) Debug.Log((string)item); else if (item.isInt) Debug.Log((int)item) } // "Leokk" // 2
实例自带一些布尔类型的属性,用来判断当前键值的类型
IsArray
,IsBoolean
,IsDouble
,IsInt
,IsLong
,IsObject
,IsString
- 使用属性
Keys
配合foreach
关键字进行循环,JsonData 实现了IDictionary
接口。此方法不能循环数组形式的 JsonData 实例。
foreach (string key in jsonDataA.Keys) { key; (string)jsonDataA[key]; jsonDataA[key].ToJson(); } // "name" "Leokk" "Leokk" // "age" Error int 不能转为 string "2"
在第二次循环中,试图将数字 2 强制转换为 string
所以会报错。
访问属性
- JSON 字符串转换为 JsonData 实例
petA["name"]; // JsonData 类型 Leokk petA["name"].ToJson(); // "Leokk" petA["age"].ToJson(); // "2" (string)jsonDataA["name"]; // "Leokk" (int)jsonDataA["age"] // 2
2.JsonData / 类实例转换为 JSON 字符串
string reloadA = JsonMapper.ToJson(jsonDataA); string reloadA = jsonDataA.ToJson(); // "{ 'name': 'Leokk', 'age': 2 }" string reoloadB = JsonMapper.ToJson(petB); // "{ 'name': 'Misha', 'age': 3 }"
这里需要注意一点,JsonData 实例自带 ToJson
方法将自身转为字符串。静态方法 JsonMapper.ToJson
主要用于将其他的类实例(如:petB
)转化为 JSON 字符串.
清空
实例方法 .Clear
用于清空实例内部全部属性。返回 []
或 {}
。暂没发现有删除单个属性的方法。
最后
Json文件里有中文的话,TextAsset得到的对象无法识别,需要在如NotePad++这种文本编辑器里编码改为UTF-8 无BOM格式编码,得到文本内容后,使用litjson提供JsonMapper.ToObject方法,将文本转成jsondata
命名空间中还有 JsonReader
,JsonWriter
类,用法参考链接 是ToJson, ToObject 的具体实现方法。
代码举例II:
JsonMapper
- 使用JsonMapper将JsonData解析到Json字符串
JsonData jsondata = new JsonData(); jsondata["name"] = "ZhangSan"; jsondata["ID"] = 123456; jsondata["sex"] = "male"; string json = JsonMapper.ToJson(jsondata); print(json);
运行结果:<font color=green>{"name":"ZhangSan","ID":123456,"sex":"male"}</font>
- 使用JsonMapper将对象解析到Json字符串
自定义Player类
public class Player { public string name; public int ID; public string sex; } Player player = new Player(); player.name = "ZhangSan"; player.ID = 123456; player.sex = "male"; string json = JsonMapper.ToJson(player); print(json);
运行结果:<font color=green>{"name":"ZhangSan","ID":123456,"sex":"male"}</font>
- 使用JsonMapper将Json字符串解析到JsonData
public static JsonData ToObject(string json);
将上例中的Json字符串解析成JsonData
JsonData jsondata = JsonMapper.ToObject(json); print(jsondata["name"] + " " + jsondata["ID"] + " " + jsondata["sex"]);
运行结果:<font color=green> ZhangSan 123456 male</font>
- 使用JsonMapper将Json字符串解析到对象
public static T ToObject<T>(string json);
将上例中的json字符串解析成player对象
Player player1 = JsonMapper.ToObject<Player>(json); print(player1.name +" " + player1.ID +" "+ player1.sex); 运行结果:<font color=green> ZhangSan 123456 male</font>
Jsondata的类型转换
- Jsondata中定义了五种隐式转换,可以将(bool、double、int32、int64、string)类型隐式转换成Jsondata类型。
JsonData jsondata = new JsonData(); jsondata["name"] = "ZhangSan"; jsondata["ID"] = 123456; //jsondata["info"] = new int[] { 1, 2, 3 }; jsondata["info"] = JsonMapper.ToObject(JsonMapper.ToJson(new int[] {1,2,3})); string json = jsondata.ToJson(); print(json);
运行结果:<font color=green>{"name":"ZhangSan","ID":123456,"info":[1,2,3]}</font>
- Jsondata中定义了五种显式转换,可以将Jsondata类型显示转换成(bool、double、int32、int64、string)类型。
-
string name = (string)jsondata["name"]; int id = (int)jsondata["ID"]; // int[] info = (int[])jsondata["info"]; int[] info = new int[] { }; info = JsonMapper.ToObject<int[]>(jsondata["info"].ToJson()); foreach (int i in info) print(i);