[精品]对象和xml文件的转换
对象和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 ( ) ;
,? }
得到的输出结果如下所示。
,,
,,
Root Text
,, The text of the sample element
,,
2、使用XmlSerializer进行XML操作
先提供两个对象的序列化和反序列化的封装函数,如下所示。 , ///
, /// 对象序列化XML到文件中
, ///
, ///
文件路径 , ///
对象 , ///
对象类型 , 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;
,, }
,? }
,,
,, ///
,, /// XML反序列化
,, ///
,, ///
文件路径 ,, ///
对象类型 ,, ///
,, 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
list = new List();
,, }
调用序列化函数的代码例子如下所示
,, 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内容如下所示。
,,,
,,,
,,,
,,, f8a8b323-5c56-4c21-9ddf-1cd30f78dfca ,,, 20010001 ,,, 张三 ,,, 男
,,? 1999-1-1 ,,,
,,,
,,, bbb36378-ec27-4e20-ad4b-2d2dc7e142e4 ,,, 20020001 ,,, 李氏 ,,, 女
,,, 1998-1-1 ,,,
,,,
反序列化的操作也比较简单,不再赘述。
3)把对象实例化到XML中并进行加密处理
首先我们定义两个序列化加密、解码并反序列化的函数如下所示。
, ///
, /// XML序列化并加密
, ///
, /// 文件路径
, /// 对象
, /// 对象类型
, ///
, 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;
,, }
,? }
,,
,, ///
,, /// 解密并进行XML反序列化
,, ///
,, /// 文件路径
,, /// 对象类型
,, ///
,, 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"); ,,? }
,,, }
,,, }