Unity序列化之XML,JSON--------合成與解析

1.先介紹一下 XML 和 JSON 是什麼東西吧?html

      (1)XMLjson

擴展標記語言 (Extensible Markup Language, XML) ,用於標記電子文件使其具備結構性的標記語言,能夠用來標記數據、定義數據類型,是一種容許用戶對本身的標記語言進 行定義的源語言。 XML使用DTD(document type definition)文檔類型定義來組織數據;格式統一,跨平臺和語言,早已成爲業界公認的標準。
XML是標準通用標記語言 (SGML) 的子集,很是適合 Web 傳輸。XML 提供統一的方法來描述和交換獨立於應用程序或供應商的結構化數據。數組

      (2)Json服務器

JSON(JavaScript Object Notation)一種輕量級的數據交換格式,具備良好的可讀和便於快速編寫的特性。可在不一樣平臺之間進行數據交換。JSON採用兼容性很高的、徹底獨立於語言文本格式,同時也具有相似於C語言的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)體系的行爲。這些特性使JSON成爲理想的數據交換語言。app

        說了那麼多,其實就是數據的兩種保存格式。主要用於配置文件,描述數據,存儲數據,數據傳輸等等。ui

 

2.由於Xml和Json均可以辦到這些事情,那麼它們之間有什麼區別麼?各自的優缺點?spa

      (1)XMLcode

優勢:格式統一,符合標準;.容易與其餘系統進行遠程交互,數據共享比較方便。xml

        缺點:XML文件龐大,文件格式複雜,傳輸佔帶寬;服務器端和客戶端解析XML花費較多的資源和時間;須要花費大量代碼來解析XML;htm

      (2)Json

 

優勢:數據格式比較簡單,易於讀寫,格式都是壓縮的,佔用帶寬小;.支持多種語言;

        缺點:可讀性較xml略差;

         總而言之,二者能夠相互轉換,功能都是相差無幾的。可是json比xml較好,但xml更加通用。

 

3.XML使用的簡單介紹.

a.先來看一段簡單的xml代碼。

 

  1.  
    <team name="Dreamer">
  2.  
    <student>
  3.  
    <name>Tom</name>
  4.  
    <age>20</age>
  5.  
    <id>20111234</id>
  6.  
    </student>
  7.  
    <student>
  8.  
    <name>Shierly</name>
  9.  
    <age>19</age>
  10.  
    <id>20113210</id>
  11.  
    </student>
  12.  
    <student>
  13.  
    <name>Lili</name>
  14.  
    <age>21</age>
  15.  
    <id>20111110</id>
  16.  
    </student>
  17.  
    </team>

很顯然,能夠看出來,這段代碼描述的是一個名叫Dreamer的團隊有三個成員,還分別記錄了這三個成員的相關信息。因此能夠看出來XML的可讀性十分強。因此咱們能夠用XML去描述 咱們代碼中的一些數據關係,描述一個對象。這也就是將對象序列化。而後使用的地方再將xml文件解析出來從新組成原來的對象,這就實現了複雜數據的傳輸。

b.在untiy中用代碼生成xml文件。( 可使用C#自帶的庫,不須要引入其餘庫。using System.Xml )
  1.  
    public void CreateXML()
  2.  
    {
  3.  
     
  4.  
    //xml保存的路徑,注意路徑。
  5.  
    string filepath = "E:/my.xml";
  6.  
    //繼續判斷當前路徑下是否有該文件
  7.  
    if(!File.Exists (filepath))
  8.  
    {
  9.  
    //建立XML文檔實例
  10.  
    XmlDocument xmlDoc = new XmlDocument();
  11.  
    //建立root節點,也就是最上一層節點
  12.  
    XmlElement root = xmlDoc.CreateElement( "team");
  13.  
    root.SetAttribute( "name", "Dreamer");
  14.  
    //繼續建立下一層節點
  15.  
    XmlElement student = xmlDoc.CreateElement( "student");
  16.  
     
  17.  
    //繼續建立下一層節點
  18.  
    XmlElement name = xmlDoc.CreateElement( "name");
  19.  
    //設置節點中的數值
  20.  
    name.InnerText = "Tom";
  21.  
    XmlElement age = xmlDoc.CreateElement( "age");
  22.  
    age.InnerText = "20";
  23.  
    XmlElement id = xmlDoc.CreateElement( "id");
  24.  
    id.InnerText = "20111234";
  25.  
     
  26.  
    //把節點一層一層的添加至XMLDoc中 ,請仔細看它們之間的前後順序,這將是生成XML文件的順序
  27.  
    student.AppendChild(name);
  28.  
    student.AppendChild(age);
  29.  
    student.AppendChild(id);
  30.  
    root.AppendChild(student);
  31.  
     
  32.  
    student = xmlDoc.CreateElement( "student");
  33.  
    name = xmlDoc.CreateElement( "name");
  34.  
    name.InnerText = "Shierly";
  35.  
    age = xmlDoc.CreateElement( "age");
  36.  
    age.InnerText = "19";
  37.  
    id = xmlDoc.CreateElement( "id");
  38.  
    id.InnerText = "20113210";
  39.  
    student.AppendChild(name);
  40.  
    student.AppendChild(age);
  41.  
    student.AppendChild(id);
  42.  
    root.AppendChild(student);
  43.  
     
  44.  
    student = xmlDoc.CreateElement( "student");
  45.  
    name = xmlDoc.CreateElement( "name");
  46.  
    name.InnerText = "Lili";
  47.  
    age = xmlDoc.CreateElement( "age");
  48.  
    age.InnerText = "21";
  49.  
    id = xmlDoc.CreateElement( "id");
  50.  
    id.InnerText = "20111110";
  51.  
    student.AppendChild(name);
  52.  
    student.AppendChild(age);
  53.  
    student.AppendChild(id);
  54.  
    root.AppendChild(student);
  55.  
     
  56.  
    xmlDoc.AppendChild(root);
  57.  
    //把XML文件保存至本地
  58.  
    xmlDoc.Save(filepath);
  59.  
    }
  60.  
     
  61.  
    }
這個代碼運行後就會在目標文件夾中生成一個xml文件而文件內容就是1中的那段xml代碼。
能夠看出來 XmlElement 是基本結構單元。也就是xml中的一對<Name></Name>。
1.咱們能夠對這個結構單元添加屬性:xmlelement.SetAttribute(name,value)。
2.也能夠對這個結構單元添加子結構單元:xmlelement.AppendChild(childelement)。
3.若是該結構單元沒有子結構了還能夠設置它的內容值:xmlelement.InnerText = value.
c.更新xml文件( 修改第三個學生的名字爲Jack )
  1.  
    public void UpdateXml()
  2.  
    {
  3.  
    string filepath = "E:/my.xml";
  4.  
    if (File.Exists(filepath))
  5.  
    {
  6.  
    XmlDocument xmlDoc = new XmlDocument();
  7.  
    //根據路徑將XML讀取出來
  8.  
    xmlDoc.Load(filepath);
  9.  
    //獲得team下的全部student節點.
  10.  
    XmlNodeList studentlist = xmlDoc.SelectSingleNode( "team").ChildNodes;
  11.  
    //遍歷全部子節點
  12.  
    foreach (XmlElement student in studentlist)
  13.  
    {
  14.  
     
  15.  
    XmlNode name = student.SelectSingleNode( "name");
  16.  
    if (name.InnerText.Equals("Lili"))
  17.  
    {
  18.  
    name.InnerText = "Jack";
  19.  
    }
  20.  
    }
  21.  
    xmlDoc.Save(filepath);
  22.  
    }
  23.  
    }
請注意:xmlelement.SelectSingleNode(name)是選取該節點下第一個子節點中名字爲name的節點。必須是父子,不能隔兩級及以上。
更新結果:
  1.  
    <team name="Dreamer">
  2.  
    <student>
  3.  
    <name>Tom</name>
  4.  
    <age>20</age>
  5.  
    <id>20111234</id>
  6.  
    </student>
  7.  
    <student>
  8.  
    <name>Shierly</name>
  9.  
    <age>19</age>
  10.  
    <id>20113210</id>
  11.  
    </student>
  12.  
    <student>
  13.  
    <name>Jack</name>
  14.  
    <age>21</age>
  15.  
    <id>20111110</id>
  16.  
    </student>
  17.  
    </team>
d.添加xml屬性( 增長一個學生:Sharo,22,20112312 )
  1.  
    public void InsertXml()
  2.  
    {
  3.  
    string filepath = "E:/my.xml";
  4.  
    if (File.Exists(filepath))
  5.  
    {
  6.  
    XmlDocument xmlDoc = new XmlDocument();
  7.  
    //根據路徑將XML讀取出來
  8.  
    xmlDoc.Load(filepath);
  9.  
     
  10.  
    XmlNode team = xmlDoc.SelectSingleNode( "team");
  11.  
    XmlElement newstudent = xmlDoc.CreateElement( "student");
  12.  
     
  13.  
    XmlElement name = xmlDoc.CreateElement( "name");
  14.  
    name.InnerText = "Sharo";
  15.  
     
  16.  
    XmlElement age = xmlDoc.CreateElement( "age");
  17.  
    age.InnerText = "22";
  18.  
     
  19.  
    XmlElement id = xmlDoc.CreateElement( "id");
  20.  
    id.InnerText = "20112312";
  21.  
    //向新隊員添加屬性
  22.  
    newstudent.AppendChild(name);
  23.  
    newstudent.AppendChild(age);
  24.  
    newstudent.AppendChild(id);
  25.  
    //將新隊員添加到團隊裏面
  26.  
    team.AppendChild(newstudent);
  27.  
     
  28.  
    xmlDoc.Save(filepath);
  29.  
    }
  30.  
    }
上述代碼演示了添加節點,其實對節點添加屬性也是同樣的。
更新結果:
  1.  
    <team name="Dreamer">
  2.  
    <student>
  3.  
    <name>Tom</name>
  4.  
    <age>20</age>
  5.  
    <id>20111234</id>
  6.  
    </student>
  7.  
    <student>
  8.  
    <name>Shierly</name>
  9.  
    <age>19</age>
  10.  
    <id>20113210</id>
  11.  
    </student>
  12.  
    <student>
  13.  
    <name>Jack</name>
  14.  
    <age>21</age>
  15.  
    <id>20111110</id>
  16.  
    </student>
  17.  
    <student>
  18.  
    <name>Sharo</name>
  19.  
    <age>22</age>
  20.  
    <id>20112312</id>
  21.  
    </student>
  22.  
    </team>
e.刪除xml節點(刪除Tom學生的信息)
  1.  
    public void DeleteXml()
  2.  
    {
  3.  
    string filepath = "E:/my.xml";
  4.  
    if (File.Exists(filepath))
  5.  
    {
  6.  
    XmlDocument xmlDoc = new XmlDocument();
  7.  
    //根據路徑將XML讀取出來
  8.  
    xmlDoc.Load(filepath);
  9.  
     
  10.  
    XmlNode team = xmlDoc.SelectSingleNode( "team");
  11.  
    XmlNodeList studentlist = team.ChildNodes;
  12.  
     
  13.  
    foreach(XmlNode student in studentlist)
  14.  
    {
  15.  
    XmlNode name = student.SelectSingleNode( "name");
  16.  
    if(name.InnerText.Equals("Tom"))
  17.  
    {
  18.  
    team.RemoveChild(student);
  19.  
    }
  20.  
    }
  21.  
     
  22.  
    xmlDoc.Save(filepath);
  23.  
    }
  24.  
    }
可使用 xmlelement.RemoveAll() 刪除全部子節點
更新結果:
  1.  
    <team name="Dreamer">
  2.  
    <student>
  3.  
    <name>Shierly</name>
  4.  
    <age>19</age>
  5.  
    <id>20113210</id>
  6.  
    </student>
  7.  
    <student>
  8.  
    <name>Jack</name>
  9.  
    <age>21</age>
  10.  
    <id>20111110</id>
  11.  
    </student>
  12.  
    <student>
  13.  
    <name>Sharo</name>
  14.  
    <age>22</age>
  15.  
    <id>20112312</id>
  16.  
    </student>
  17.  
    </team>
f.解析xml文件
  1.  
    public void LoadXml()
  2.  
    {
  3.  
    string filepath = "E:/my.xml";
  4.  
    if (File.Exists(filepath))
  5.  
    {
  6.  
    XmlDocument xmlDoc = new XmlDocument();
  7.  
    //根據路徑將XML讀取出來
  8.  
    xmlDoc.Load(filepath);
  9.  
     
  10.  
    XmlElement team = (XmlElement)xmlDoc.SelectSingleNode( "team");
  11.  
    string teamname = team.GetAttribute("name");
  12.  
     
  13.  
    Console.WriteLine( "這是一個名叫\"" + teamname + "\"的隊伍:");
  14.  
    XmlNodeList studentlist = team.ChildNodes;
  15.  
    Console.WriteLine( "一共有" + studentlist.Count + "人");
  16.  
    foreach (XmlNode student in studentlist)
  17.  
    {
  18.  
    XmlNode name = student.SelectSingleNode( "name");
  19.  
    XmlNode age = student.SelectSingleNode( "age");
  20.  
    XmlNode id = student.SelectSingleNode( "id");
  21.  
    Console.WriteLine( "姓名:" + name.InnerText + ",年齡:" + age.InnerText + ",學號:" + id.InnerText);
  22.  
    }
  23.  
     
  24.  
    xmlDoc.Save(filepath);
  25.  
    }
  26.  
    }
在實際狀況中,咱們通常在解析xml的時候去給對象相關屬性賦值。至關因而在還原xml中表示的對象數據。
輸出結果:
  1.  
    這是一個名叫 "Dreamer"的隊伍:
  2.  
    一共有 3人
  3.  
    姓名:Shierly,年齡: 19,學號:20113210
  4.  
    姓名:Jack,年齡: 21,學號:20111110
  5.  
    姓名:Sharo,年齡: 22,學號:20112312
 
4.Json使用的簡單介紹.(Json使用須要下載LitJson的包)
 
a.先來看看json代碼
  1.  
    {
  2.  
    "Name" : "Dreamer",
  3.  
    "Number" : 3,
  4.  
    "Member" :
  5.  
    [
  6.  
    {
  7.  
    "Name" : "Tom",
  8.  
    "Age" : 20,
  9.  
    "Id" : "20111234"
  10.  
    },
  11.  
    {
  12.  
    "Name" : "Jack",
  13.  
    "Age" : 22,
  14.  
    "Id" : "20112312"
  15.  
    }
  16.  
    ]
  17.  
    }
恩這個描述看起來比較熟悉?沒錯,這就是鍵值對的表現方式。相比起xml來講json省略了不少冗餘的表達格式。
仔細看能夠發現json的基本結構單元就是以{ }括起來的一組鍵值對,而這個結構單元也能夠做爲值。而[ ]中括號就表示數組,數組的每一個元素都是一個結構單元。
鍵值對的表示是 key :value,鍵值對之間用,隔開。
b.生成json代碼
  1.  
    public void CreateJson()
  2.  
    {
  3.  
    string path = "E:/json.txt";
  4.  
    FileInfo t = new FileInfo(path);
  5.  
     
  6.  
    StreamWriter sw = t.CreateText();
  7.  
     
  8.  
    StringBuilder sb = new StringBuilder();
  9.  
    JsonWriter writer = new JsonWriter(sb);
  10.  
    //至關於寫下了'{'
  11.  
    writer.WriteObjectStart();
  12.  
    //至關於寫下了"Name":
  13.  
    writer.WritePropertyName( "Name");
  14.  
    //至關於寫下了"Dreamer"
  15.  
    writer.Write( "Dreamer");
  16.  
     
  17.  
    writer.WritePropertyName( "Number");
  18.  
    writer.Write( "3");
  19.  
     
  20.  
    writer.WritePropertyName( "Member");
  21.  
    //至關於寫下了'['
  22.  
    writer.WriteArrayStart();
  23.  
     
  24.  
    writer.WriteObjectStart();
  25.  
    writer.WritePropertyName( "Name");
  26.  
    writer.Write( "Tom");
  27.  
    writer.WritePropertyName( "Age");
  28.  
    writer.Write( "20");
  29.  
    writer.WritePropertyName( "Id");
  30.  
    writer.Write( "20111234");
  31.  
    //至關於寫下了'}'
  32.  
    writer.WriteObjectEnd();
  33.  
     
  34.  
    writer.WriteObjectStart();
  35.  
    writer.WritePropertyName( "Name");
  36.  
    writer.Write( "Jack");
  37.  
    writer.WritePropertyName( "Age");
  38.  
    writer.Write( "22");
  39.  
    writer.WritePropertyName( "Id");
  40.  
    writer.Write( "20112312");
  41.  
    writer.WriteObjectEnd();
  42.  
    //至關於寫下了']'
  43.  
    writer.WriteArrayEnd();
  44.  
    writer.WriteObjectEnd();
  45.  
    sw.WriteLine(sb.ToString());
  46.  
    sw.Close();
  47.  
    }
這段代碼就是生成上面json代碼的生成代碼。
很顯然,json生成的代碼更像是html這類代碼同樣,按照生成文件的格式調用對應的API。不過,json有更好的方式,它能夠直接對對象序列化。
看下面的例子:
  1.  
    using UnityEngine;
  2.  
    using LitJson;
  3.  
    public class A
  4.  
    {
  5.  
    public string name = "yzl";
  6.  
    public int old = 20;
  7.  
    }
  8.  
    public class Test : MonoBehaviour
  9.  
    {
  10.  
    void Start()
  11.  
    {
  12.  
    A a = new A();
  13.  
    Debug.Log(JsonMapper.ToJson(a));
  14.  
    }
  15.  
    }
觀察控制檯輸出:{"name":"yzl","old":20}
發現,json能夠直接對對象裏面的屬性序列化生成對應的json文件。這就是很方便的地方了。固然,xml也有這個功能,可是須要對類的屬性添加節點標籤。相比json要麻煩一些。
c.json的增刪改( 增長隊伍地址屬性,刪除隊伍人數屬性,修改隊名 )
  1.  
    using UnityEngine;
  2.  
    using System.Collections;
  3.  
    using System;
  4.  
    using System.Collections.Generic;
  5.  
    using LitJson;
  6.  
    using System.IO;
  7.  
    public class Test : MonoBehaviour
  8.  
    {
  9.  
    void Start()
  10.  
    {
  11.  
    StreamReader sr = File.OpenText( "E:/json.txt");
  12.  
    string strline = sr.ReadToEnd();
  13.  
     
  14.  
    JsonData jd = JsonMapper.ToObject(strline);
  15.  
     
  16.  
    //修改隊名
  17.  
    jd[ "Name"] = "Winer";
  18.  
    //添加隊伍地址屬性
  19.  
    jd[ "Address"] = "Sichuan";
  20.  
    //刪除隊伍人數屬性
  21.  
    ((IDictionary)jd).Remove( "Number");
  22.  
    Debug.Log(jd.ToJson());
  23.  
     
  24.  
    sr.Close();
  25.  
    }
  26.  
    }
能夠看出來json使用起來要比xml方便許多,解析的使用方法和C#的字典相似。
d.json的解析查看
  1.  
    using UnityEngine;
  2.  
    using System.Collections;
  3.  
    using System;
  4.  
    using System.Collections.Generic;
  5.  
    using LitJson;
  6.  
    using System.IO;
  7.  
     
  8.  
    public class Test : MonoBehaviour
  9.  
    {
  10.  
    void Start()
  11.  
    {
  12.  
    StreamReader sr = File.OpenText( "E:/json.txt");
  13.  
    string strline = sr.ReadToEnd();
  14.  
     
  15.  
    JsonData jd = JsonMapper.ToObject(strline);
  16.  
     
  17.  
    Debug.Log( "隊伍名:" + jd["Name"]);
  18.  
    Debug.Log( "隊伍人數:" + jd["Number"]);
  19.  
     
  20.  
    for (int i = 0; i < jd["Member"].Count; i++)
  21.  
    {
  22.  
    Debug.Log( "姓名:" + jd["Member"][i]["Name"] + ",年齡:" + jd["Member"][i]["Age"] + ",學號:" + jd["Member"][i]["Id"]);
  23.  
    }
  24.  
    sr.Close();
  25.  
    }
  26.  
    }
輸出結果:
隊伍名:Dreamer
隊伍人數:3
姓名:Tom,年齡:20,學號:20111234
姓名:Jack,年齡:22,學號:20112312
相關文章
相關標籤/搜索