首页 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;
        }
        ///
        /// 序列化对象对象为XML字符串
        ///

        public static string Serialize(object ObjectToSerialize)
        {
            字符串结果 = null ;
            try
            {
            XmlSerializer xmlSerializer = new XmlSerializer(ObjectToSerialize.GetType());

            使用 (MemoryStream memoryStream = new MemoryStream())
            {
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, new UTF8Encoding(false));
                xmlTextWriter.Formatting = Formatting.Indented;
                xmlS erializer.Serialize(xmlTextWriter, ObjectToSerialize);
                xmlTextWriter.Flush( );
                xmlTextWriter.Close();
                UTF8Encoding uTF8Encoding = new UTF8Encoding(false, true);
                result= uTF8Encoding.GetString(memoryStream.ToArray());
            }
            }
            catch (Exception insideException)
            {
               throw new ApplicationException("无法序列化对象:" ObjectToSerialize.GetType().Name, innerException);
            }
            返回结果;
}
    }


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

复制代码代码如下:


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

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++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教程
1662
14
CakePHP 教程
1419
52
Laravel 教程
1312
25
PHP教程
1262
29
C# 教程
1235
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(可扩展的标记语言)是一种用于人类可读性和机器解析的多功能文本标记语言。它通常用于数据存储

如何将 MySQL 查询结果数组转换为对象? 如何将 MySQL 查询结果数组转换为对象? Apr 29, 2024 pm 01:09 PM

将MySQL查询结果数组转换为对象的方法如下:创建一个空对象数组。循环结果数组并为每一行创建一个新的对象。使用foreach循环将每一行的键值对赋给新对象的相应属性。将新对象添加到对象数组中。关闭数据库连接。

如何使用 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,提取产品信息,转换并将其存储到数据库中。

PHP 函数如何返回对象? PHP 函数如何返回对象? Apr 10, 2024 pm 03:18 PM

PHP函数可以通过使用return语句后跟对象实例来返回对象,从而将数据封装到自定义结构中。语法:functionget_object():object{}。这允许创建具有自定义属性和方法的对象,并以对象的形式处理数据。

C++ 函数返回对象时有什么需要注意的? C++ 函数返回对象时有什么需要注意的? Apr 19, 2024 pm 12:15 PM

在C++中,函数返回对象需要注意三点:对象的生命周期由调用者负责管理,以防止内存泄漏。避免悬垂指针,通过动态分配内存或返回对象本身来确保对象在函数返回后仍然有效。编译器可能会优化返回对象的副本生成,以提高性能,但如果对象是值语义传递的,则无需副本生成。

C++ 函数库如何进行序列化和反序列化? C++ 函数库如何进行序列化和反序列化? Apr 18, 2024 am 10:06 AM

C++函数库序列化和反序列化指南序列化:创建输出流并将其转换为存档格式。将对象序列化到存档中。反序列化:创建输入流并将其从存档格式恢复。从存档中反序列化对象。实战示例:序列化:创建输出流。创建存档对象。创建对象并将其序列化到存档中。反序列化:创建输入流。创建存档对象。创建对象并从存档中反序列化。

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

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

See all articles