首頁 php教程 php手册 深入理解:XML与对象的序列化与反序列化

深入理解:XML与对象的序列化与反序列化

Jun 13, 2016 am 11:49 AM
xml 主要 物件 序列化 文章 深入 理解

这篇文章主要讲述XML与对象的序列化与反序列化。并且会附上一些简单的序列化与反序列化方法,供大家使用。
假设我们在一个Web项目中有这样两个类

复制代码 代码如下:


public class Member
    {
      public string Num { get; set; }
      public string Name { get; set; }
    }
    public class Team
    {
       public  string Name;
       public  List Members { get; set; }
    }


假设我们需要把Team类的一个实例POST到一个URL,
当然,使用Form隐藏域提交就可以完成该功能。
如果该Team包括30条数据呢?
为了区分每个Member,我们得给参数的名字加上后缀。这就要一大串的隐藏域来完成:

复制代码 代码如下:



@model Team





...






还敢想象一下如果Team再复杂一些,嵌套再多一些的情况么?
呃,即使你愿意这么传数据,对方看到一坨参数名就够头疼了。
我们都知道对象是不能在网络中直接传输的,不过还有补救的办法。
XML(Extensible Markup Language)可扩展标记语言,本身就被设计用来存储数据,任何一个对象都可以用XML来描述。以Team类为例:

复制代码 代码如下:




  Development
 
   
      001
      Marry
   

   
      002
      John
   

 



这样一个XML文档就表示了Team一个实例。
聪明的看官应该已经想到,XML是可以作为对象信息的载体在网络中传输,因为它是文本形式的。
怎么进行XML文档与对象的相互转换呢?

XmlSerializer类就是干这个活的。
      命名空间:System.Xml.Serialization
     程序集:System.Xml(在 system.xml.dll 中)
现在这里展示了一个提供序列化与反序列化方法的EncodeHelper类。
Deserialize方法将XML字符串转换为指定类型的对象;
Serialize方法则将对象转换为XML字符串。

复制代码 代码如下:


///


    /// 提供xml文档序列化 反序列化
    ///

    public sealed class EncodeHelper
    {
        ///
        /// 反序列化XML字符串为指定类型
        ///

        public static object Deserialize(string Xml, Type ThisType)
        {
            XmlSerializer xmlSerializer = new XmlSerializer(ThisType);
            object result;
            try
            {
                using (StringReader stringReader = new StringReader(Xml))
                {
                    result = xmlSerializer.Deserialize(stringReader);
                }
            }
            catch (Exception innerException)
            {
                bool flag = false;
                if (Xml != null)
                {
                    if (Xml.StartsWith(Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble())))
                    {
                        flag = true;
                    }
                }
                throw new ApplicationException(string.Format("Couldn't parse XML: '{0}'; Contains BOM: {1}; Type: {2}.",
                Xml, flag, ThisType.FullName), innerException);
            }
            return result;
        }
        ///
        /// 序列化object对象为XML字符串
        ///

        public static string Serialize(object ObjectToSerialize)
        {
            string result = null ;
            try
            {
            XmlSerializer xmlSerializer = new XmlSerializer(ObjectToSerialize.GetType());

            using (MemoryStream memoryStream = new MemoryStream())
            {
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, new UTF8Encoding(false));
                xmlTextWriter.Formatting = Formatting.Indented;
                xmlSerializer.Serialize(xmlTextWriter, ObjectToSerialize);
                xmlTextWriter.Flush();
                xmlTextWriter.Close();
                UTF8Encoding uTF8Encoding = new UTF8Encoding(false, true);
                result= uTF8Encoding.GetString(memoryStream.ToArray());
            }
            }
            catch (Exception innerException)
            {
                throw new ApplicationException("Couldn't Serialize Object:" + ObjectToSerialize.GetType().Name, innerException);
            }
            return result;
        }
    }


要使用这个类需要添加以下引用
using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
下面我们用一个控制台程序来演示一下这个类是如何工作的。这里是程序的Main函数。

复制代码 代码如下:


static void Main(string[] args)
        {
            List Members = new List();
            Member member1 = new Member { Name = "Marry", Num = "001" };
            Member member2 = new Member { Name = "John", Num = "002" };
            Members.Add(member1);
            Members.Add(member2);
            Team team = new Team { Name = "Development", Members = Members };
            var xml =EncodeHelper.Serialize(team);//序列化
            Console.Write(xml);//打印序列化后的XML字符串
            Console.ReadLine();
            Team newTeam = EncodeHelper.Deserialize(xml, typeof(Team)) as Team;//反序列化时需要显式的进行类型转换
            Console.WriteLine("Team Name:"+newTeam.Name);//显示反序列化后的newTeam对象
            foreach (var member in newTeam.Members)
            {
                Console.WriteLine("Member Num:" + member.Num);
                Console.WriteLine("Member Name:" + member.Name);
            }
            Console.ReadLine();
        }


在执行完Console.Write(xml)这行代码后,就可以看到打印出来的XML文档了。

复制代码 代码如下:




  Development
 
   
      001
      Marry
   

   
      002
      John
   

 



与我在文章开头给出的例子是一模一样的。
最终反序列化出来的newTeam对象打印出来是这样的结果。
Team Name:Development
Member Num:001
Member Name:Marry
Member Num:002
Member Name:John
回到我们开头的Web通信的例子,
利用XML序列化与反序列化来进行对象传递,我们只需要把需要传递的对象序列化为XML字符串,使用一个隐藏域进行form提交就可以搞定咯!
接收方再将接收到的XML字符串反序列化成预设的对象即可。前提是双方必须约定序列化与反序列化的过程一致,且对象相同。

最后我们来看一下怎么利用一些特性来控制序列化与反序列化操作的过程。我们把开始的类改一下:

复制代码 代码如下:


public class Member
    {
        [XmlElement("Member_Num")]
        public string Num { get; set; }
        public string Name { get; set; }
    }
    [XmlRoot("Our_Team")]
    public class Team
    {
        [XmlIgnore]public string Name;
        public List Members { get; set; }
    }


然后我们再次执行刚才的控制台程序,序列化结果变成了这样:

复制代码 代码如下:




 
   
      001
      Marry
   

   
      002
      John
   

 



本来的根节点Team变成了Our_Team,Member的子节点Num变成了Member_Num,并且Team的Name子节点被忽略了。
可见特性XmlRoot可以控制根节点的显示和操作过程,XmlElement则针对子节点。如果某些成员被标记XmlIgnore,则在序列化与反序列化过程中会被忽略。
这些特性的具体内容可以在MSDN查看,就不多讲了。
有了这些知识,在网络中传递对象数据应该已经难不倒各位看官了把。^_^
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
今日頭條發布文章怎麼有收益?今日頭條發布文章獲得更多收益方法! 今日頭條發布文章怎麼有收益?今日頭條發布文章獲得更多收益方法! Mar 15, 2024 pm 04:13 PM

一、今日頭條發布文章怎麼有收益?今日頭條發布文章獲得更多收益方法! 1.開通基礎權益:原創文章選擇投放廣告可獲得收益,影片必須原創橫屏才會有收益。 2.開通百粉權益:粉絲量達百粉以上,微頭條、原創問答創作及問答均可獲得收益。 3.堅持原創作品:原創作品包含文章、微標題及問題等,要求300字以上。注意違規抄襲作品作為原創發布,會被扣信用分,即使有收益也會被扣除。 4.垂直度:做專業領域一類的文章,不能隨意跨領域寫文章,會得不到合適的推薦,達不到作品的專和精,難以吸引粉絲讀者。 5.活躍度:活躍度高,

您如何在PHP中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

如何使用 PHP 函數處理 XML 資料? 如何使用 PHP 函數處理 XML 資料? May 05, 2024 am 09:15 AM

使用PHPXML函數處理XML資料:解析XML資料:simplexml_load_file()和simplexml_load_string()載入XML檔案或字串。存取XML資料:利用SimpleXML物件的屬性和方法來取得元素名稱、屬性值和子元素。修改XML資料:使用addChild()和addAttribute()方法新增元素和屬性。序列化XML資料:asXML()方法將SimpleXML物件轉換為XML字串。實戰案例:解析產品饋送XML,提取產品信息,轉換並將其儲存到資料庫中。

如何將 MySQL 查詢結果陣列轉換為物件? 如何將 MySQL 查詢結果陣列轉換為物件? Apr 29, 2024 pm 01:09 PM

將MySQL查詢結果陣列轉換為物件的方法如下:建立一個空物件陣列。循環結果數組並為每一行建立一個新的物件。使用foreach迴圈將每一行的鍵值對賦給新物件的對應屬性。將新物件加入到物件數組中。關閉資料庫連線。

PHP 函數如何傳回物件? PHP 函數如何傳回物件? Apr 10, 2024 pm 03:18 PM

PHP函數可以透過使用return語句後接物件實例來傳回對象,從而將資料封裝到自訂結構中。語法:functionget_object():object{}。這允許創建具有自訂屬性和方法的對象,並以對象的形式處理資料。

C++ 函式庫如何進行序列化與反序列化? C++ 函式庫如何進行序列化與反序列化? Apr 18, 2024 am 10:06 AM

C++函式庫序列化和反序列化指南序列化:建立輸出流並將其轉換為存檔格式。將物件序列化到存檔中。反序列化:建立輸入流並將其從存檔格式還原。從存檔中反序列化物件。實戰範例:序列化:建立輸出流。建立存檔物件。建立物件並將其序列化到存檔中。反序列化:建立輸入流。建立存檔物件。建立物件並從存檔中反序列化。

C++ 函式回傳物件時有什麼需要注意的? C++ 函式回傳物件時有什麼需要注意的? Apr 19, 2024 pm 12:15 PM

在C++中,函數傳回物件需要注意三點:物件的生命週期由呼叫者負責管理,以防止記憶體洩漏。避免懸垂指針,透過動態分配記憶體或返回物件本身來確保物件在函數返回後仍然有效。編譯器可能會最佳化傳回物件的副本生成,以提高效能,但如果物件是值語義傳遞的,則無需副本生成。

Java序列化如何影響效能? Java序列化如何影響效能? Apr 16, 2024 pm 06:36 PM

序列化对Java性能的影响:序列化过程依赖于反射,会显著影响性能。序列化需要创建字节流存储对象数据,导致内存分配和处理成本。序列化大对象会消耗大量内存和时间。序列化后的对象在网络上传输时会增加负载量。

See all articles