談?wù)剬?duì)象和XML文件的轉(zhuǎn)換
很多時(shí)候,我們開(kāi)發(fā)程序都需要使用到對(duì)象的XML序列化和反序列化,對(duì)象的XML序列化和反序列化,既可以使用XML對(duì)象(XmlDocument )進(jìn)行操作,也可以使用XmlSerializer進(jìn)行操作,兩個(gè)各有優(yōu)點(diǎn),就操作性而已,我傾向于使用后者來(lái)操作XML。
本文介紹三種方式操作XML,普通的XDocument的API操作,方便的XmlSerializer對(duì)象序列化及反序列化操作,加密XML對(duì)象序列化操作。
1、普通的XML對(duì)象操作,利用XML對(duì)象(XmlDocument )。
一個(gè)典型的利用XmlDocument對(duì)象操作XML的例子代碼如下。
- public static void RunSnippet()
- {
- XmlDocument xmldoc = new XmlDocument ( ) ;
- //加入XML的聲明段落
- XmlNode xmlnode = xmldoc.CreateNode ( XmlNodeType.XmlDeclaration , "" , "" ) ;
- xmldoc.AppendChild (xmlnode ) ;
- //加入一個(gè)根元素
- XmlElement xmlelem = xmldoc.CreateElement ( "" , "ROOT" , "" ) ;
- XmlText xmltext = xmldoc.CreateTextNode ( "Root Text" ) ;
- xmlelem.AppendChild ( xmltext ) ;
- xmldoc.AppendChild ( xmlelem ) ;
- //加入另外一個(gè)元素
- 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 ) ;
- //保存創(chuàng)建好的XML文檔
- try
- {
- xmldoc.Save ( "c:\\data.xml" ) ;
- }
- catch ( Exception e )
- {
- //顯示錯(cuò)誤信息
- Console.WriteLine ( e.Message ) ;
- }
- Console.ReadLine ( ) ;
- }
得到的輸出結(jié)果如下所示。
- <?xml version="1.0"?>
- <ROOT>Root Text
- <SampleElement>The text of the sample element</SampleElement>
- </ROOT>
#p#
2、使用XmlSerializer進(jìn)行XML操作
先提供兩個(gè)對(duì)象的序列化和反序列化的封裝函數(shù),如下所示。
- /// <summary>
- /// 對(duì)象序列化XML到文件中
- /// </summary>
- /// <param name="path">文件路徑</param>
- /// <param name="obj">對(duì)象</param>
- /// <param name="type">對(duì)象類(lèi)型</param>
- private bool XmlSerialize(string path, object obj, Type type)
- {
- XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
- ns.Add("", "");
- try
- {
- //如果文件目錄不存在,那么創(chuàng)建目錄
- 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">對(duì)象類(lèi)型</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("", "");
是把默認(rèn)的xmlns命名空間多余的內(nèi)容去掉,這樣得到比較干凈的XML。
在使用的時(shí)候,我們需要定義好對(duì)象的實(shí)體,這樣才能給予對(duì)象進(jìn)行操作,定義的實(shí)體類(lèi)如下所示。
- [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>();
- }
調(diào)用序列化函數(shù)的代碼例子如下所示
- 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內(nèi)容如下所示。
- <?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>
反序列化的操作也比較簡(jiǎn)單,不再贅述。
#p#
3)把對(duì)象實(shí)例化到XML中并進(jìn)行加密處理
首先我們定義兩個(gè)序列化加密、解碼并反序列化的函數(shù)如下所示。
- /// <summary>
- /// XML序列化并加密
- /// </summary>
- /// <param name="path">文件路徑</param>
- /// <param name="obj">對(duì)象</param>
- /// <param name="type">對(duì)象類(lèi)型</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>
- /// 解密并進(jìn)行XML反序列化
- /// </summary>
- /// <param name="path">文件路徑</param>
- /// <param name="type">對(duì)象類(lèi)型</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;
- }
- }
這樣函數(shù)定義好后,調(diào)用和前面沒(méi)有加密的差不多,如下所示。
- 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");
- }
- }
- }
原文鏈接:http://www.cnblogs.com/wuhuacong/archive/2012/06/29/2569388.html