• 谈谈对象和XML文件的转换


    很多时候,我们开发程序都需要使用到对象的XML序列化和反序列化,对象的XML序列化和反序列化,既可以使用XML对象(XmlDocument )进行操作,也可以使用XmlSerializer进行操作,两个各有优点,就操作性而已,我倾向于使用后者来操作XML。本文介绍三种方式操作XML,普通的XDocument的API操作,方便的XmlSerializer对象序列化及反序列化操作,加密XML对象序列化操作。

    1、普通的XML对象操作,利用XML对象(XmlDocument )。

    一个典型的利用XmlDocument对象操作XML的例子代码如下。

        public static void RunSnippet()
        {
            XmlDocument xmldoc = new XmlDocument ( ) ;
        //加入XML的声明段落
        XmlNode xmlnode = xmldoc.CreateNode ( XmlNodeType.XmlDeclaration , "" , "" ) ;
        xmldoc.AppendChild (xmlnode ) ;
        //加入一个根元素
        XmlElement xmlelem = xmldoc.CreateElement ( "" , "ROOT" , "" ) ;
        XmlText xmltext = xmldoc.CreateTextNode ( "Root Text" ) ;
        xmlelem.AppendChild ( xmltext ) ;
        xmldoc.AppendChild ( xmlelem ) ;
        //加入另外一个元素
        XmlElement xmlelem2 = xmldoc.CreateElement ("SampleElement" ) ;
        xmlelem2 = xmldoc.CreateElement ( "" , "SampleElement" , "" ) ;
        xmltext = xmldoc.CreateTextNode ( "The text of the sample element" ) ;
        xmlelem2.AppendChild ( xmltext ) ;
        xmldoc.ChildNodes.Item(1).AppendChild ( xmlelem2 ) ;
        //保存创建好的XML文档
        try
        {
          xmldoc.Save ( "c:\\data.xml" ) ;
        }
        catch ( Exception e )
        {
          //显示错误信息
          Console.WriteLine ( e.Message ) ;
        }
        Console.ReadLine ( ) ;
        }

    得到的输出结果如下所示。

    <?xml version="1.0"?>
    <ROOT>Root Text
        <SampleElement>The text of the sample element</SampleElement>
    </ROOT>

    2、使用XmlSerializer进行XML操作

    先提供两个对象的序列化和反序列化的封装函数,如下所示。

            /// <summary>
            /// 对象序列化XML到文件中
            /// </summary>
            /// <param name="path">文件路径</param>
            /// <param name="obj">对象</param>
            /// <param name="type">对象类型</param>
            private bool XmlSerialize(string path, object obj, Type type)
            {
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add("", "");
    
                try
                {
                    //如果文件目录不存在,那么创建目录
                    if (!File.Exists(path))
                    {
                        FileInfo fi = new FileInfo(path);
                        if (!fi.Directory.Exists)
                        {
                            Directory.CreateDirectory(fi.Directory.FullName);
                        }
                    }
    
                    using (Stream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        XmlSerializer format = new XmlSerializer(type);
    
                        format.Serialize(stream, obj, ns);
                        stream.Close();
                    }
    
                    return true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return false;
                }
            }
    
            /// <summary>
            /// XML反序列化
            /// </summary>
            /// <param name="path">文件路径</param>
            /// <param name="type">对象类型</param>
            /// <returns></returns>
            private object XmlDeserialize(string path, Type type)
            {
                try
                {
                    using (Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        XmlSerializer formatter = new XmlSerializer(type);
                        stream.Seek(0, SeekOrigin.Begin);
                        object obj = formatter.Deserialize(stream);
                        stream.Close();
                        return obj;
                    }
                }
                catch
                {
                    return null;
                }
            }

    注意其中代码       

         XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    
         ns.Add("", "");

    是把默认的xmlns命名空间多余的内容去掉,这样得到比较干净的XML。

    在使用的时候,我们需要定义好对象的实体,这样才能给予对象进行操作,定义的实体类如下所示。

        [Serializable]
        public class UserInfo
        {                
            public string ID { get; set; }
            public string UserNo{ get; set; }
            public string UserName { get; set; }
            public string Sex { get; set; }
            public string Birthday { get; set; }
        }
    
        [Serializable]
        public class DataOfUser
        {
            [XmlElement(ElementName = "m_User")]
            public List<UserInfo> list = new List<UserInfo>();
        }

    调用序列化函数的代码例子如下所示

           private void btnUserNormal_Click(object sender, EventArgs e)
            {
                DataOfUser obj = new DataOfUser();
                UserInfo user = new UserInfo();
                user.ID=Guid.NewGuid().ToString();
                user.Sex = "";
                user.UserName = "张三";
                user.UserNo = "20010001";
                user.Birthday = "1999-1-1";
                obj.list.Add(user);
    
                user = new UserInfo();
                user.ID = Guid.NewGuid().ToString();
                user.Sex = "";
                user.UserName = "李氏";
                user.UserNo = "20020001";
                user.Birthday = "1998-1-1";
                obj.list.Add(user);
    
                try
                {
                    XmlSerialize("C:\\User.xml", obj, obj.GetType());
                    MessageUtil.ShowTips("Ok");
                }
                catch (Exception ex)
                {
                    MessageUtil.ShowError(ex.Message);
                }
            }

    这样得到的XML内容如下所示。

    <?xml version="1.0"?>
    <DataOfUser>
      <m_User>
        <ID>f8a8b323-5c56-4c21-9ddf-1cd30f78dfca</ID>
        <UserNo>20010001</UserNo>
        <UserName>张三</UserName>
        <Sex></Sex>
        <Birthday>1999-1-1</Birthday>
      </m_User>
      <m_User>
        <ID>bbb36378-ec27-4e20-ad4b-2d2dc7e142e4</ID>
        <UserNo>20020001</UserNo>
        <UserName>李氏</UserName>
        <Sex></Sex>
        <Birthday>1998-1-1</Birthday>
      </m_User>
    </DataOfUser>

    反序列化的操作也比较简单,不再赘述。

    3)把对象实例化到XML中并进行加密处理

     首先我们定义两个序列化加密、解码并反序列化的函数如下所示。

            /// <summary>
            /// XML序列化并加密
            /// </summary>
            /// <param name="path">文件路径</param>
            /// <param name="obj">对象</param>
            /// <param name="type">对象类型</param>
            /// <returns></returns>
            private bool XmlSerializeEncrypt(string path, object obj, Type type)
            {
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add("", "");
    
                try
                {
                    if (!File.Exists(path))
                    {
                        FileInfo fi = new FileInfo(path);
                        if (!fi.Directory.Exists)
                        {
                            Directory.CreateDirectory(fi.Directory.FullName);
                        }
                    }
    
                    using (Stream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
                    {       
                        string content = "";
                        using(MemoryStream ms = new MemoryStream())
                        {
                            XmlSerializer format = new XmlSerializer(type);
                            format.Serialize(ms, obj, ns);
                            ms.Seek(0, 0);
                            content = Encoding.UTF8.GetString(ms.ToArray());
                        }
    
                        string encrypt = EncodeHelper.EncryptString(content);
                        byte[] bytes = Encoding.UTF8.GetBytes(encrypt);
                        stream.Write(bytes, 0, bytes.Length);
                        stream.Close();
                    }
                    
    
                    return true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return false;
                }
            }
    
            /// <summary>
            /// 解密并进行XML反序列化
            /// </summary>
            /// <param name="path">文件路径</param>
            /// <param name="type">对象类型</param>
            /// <returns></returns>
            private object XmlDeserializeDecrypt(string path, Type type)
            {
                try
                {
                    string encrypt = File.ReadAllText(path, Encoding.UTF8);
                    string content = EncodeHelper.DecryptString(encrypt, true);
                    byte[] bytes = Encoding.UTF8.GetBytes(content);
                    using (MemoryStream stream = new MemoryStream(bytes))
                    {                  
                        XmlSerializer formatter = new XmlSerializer(type);
                        
                        stream.Seek(0, SeekOrigin.Begin);
                        object obj = formatter.Deserialize(stream);
                        stream.Close();
                        return obj;
                    }
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return null;
                }
            }

    这样函数定义好后,调用和前面没有加密的差不多,如下所示。

            private void btnUserEncrypt_Click(object sender, EventArgs e)
            {
                DataOfUser obj = new DataOfUser();
                UserInfo user = new UserInfo();
                user.ID = Guid.NewGuid().ToString();
                user.Sex = "";
                user.UserName = "张三";
                user.UserNo = "20010001";
                user.Birthday = "1999-1-1";
                obj.list.Add(user);
    
                user = new UserInfo();
                user.ID = Guid.NewGuid().ToString();
                user.Sex = "";
                user.UserName = "李氏";
                user.UserNo = "20020001";
                user.Birthday = "1998-1-1";
                obj.list.Add(user);
    
                try
                {
                    XmlSerializeEncrypt("C:\\User-Encrypt.xml", obj, obj.GetType());
                    MessageUtil.ShowTips("Ok");
                }
                catch (Exception ex)
                {
                    MessageUtil.ShowError(ex.Message);
                }
            }
    
            private void btnUserDecrypt_Click(object sender, EventArgs e)
            {
                string file = FileDialogHelper.OpenFile();
                if (!string.IsNullOrEmpty(file))
                {
                    DataOfUser info = XmlDeserializeDecrypt(file, typeof(DataOfUser)) as DataOfUser;
                    if (info != null)
                    {
                        MessageUtil.ShowTips("OK");
                    }
                }
            }
    主要研究技术:代码生成工具、会员管理系统、客户关系管理软件、病人资料管理软件、Visio二次开发、酒店管理系统、仓库管理系统等共享软件开发
    专注于Winform开发框架/混合式开发框架Web开发框架Bootstrap开发框架微信门户开发框架的研究及应用
      转载请注明出处:
    撰写人:伍华聪  http://www.iqidi.com 
        
  • 相关阅读:
    华为"128为大整数相加"机试题
    ORA-12545: 因目标主机或对象不存在, 连接失败
    VS2010 安装使用STLPort
    Debian 入门安装与配置1
    CF1072A Palindromic Twist 思维
    解决让刷新页面时不提示 "重试或取消”对话框
    php优化及高效提速问题小结
    让Tomcat支持php
    Php邮件发送源码
    使用iconv提示未知错误
  • 原文地址:https://www.cnblogs.com/wuhuacong/p/2569388.html
Copyright © 2020-2023  润新知