谈谈对象和XML文件的转换

本文详细介绍了XML序列化与反序列化的三种方式:利用XML对象(XmlDocument)进行普通操作,使用XmlSerializer对象进行序列化及反序列化操作,以及加密XML对象序列化操作。通过实例代码展示了如何实现这些操作,并提供了相应的加密与解密函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很多时候,我们开发程序都需要使用到对象的XML序列化和反序列化,对象的XML序列化和反序列化,既可以使用XML对象(XmlDocument )进行操作,也可以使用XmlSerializer进行操作,两个各有优点,就操作性而已,我倾向于使用后者来操作XML。

  本文介绍三种方式操作XML,普通的XDocument的API操作,方便的XmlSerializer对象序列化及反序列化操作,加密XML对象序列化操作。

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

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

  publicstaticvoid 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();  
                  }  
  returntrue;  
              }  
  catch (Exception ex)  
              {  
                  Console.WriteLine(ex.Message);  
  returnfalse;  
              }  
          }  
  /// <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
              {  
  returnnull;  
              }  
          } 

  注意其中代码       

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

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

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

  [Serializable]  
  publicclass 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]  
  publicclass DataOfUser  
      {  
          [XmlElement(ElementName = "m_User")]  
  public List<UserInfo> list = new List<UserInfo>();  
      } 

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

  privatevoid 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内容如下所示。

  <?xmlversion="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>
          /// <paramname="path">文件路径</param>
          /// <paramname="obj">对象</param>
          /// <paramname="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>
          /// <paramname="path">文件路径</param>
          /// <paramname="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");  
                  }  
              }  
          } 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值