谈谈对象和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开发框架 、WCF开发框架的研究及应用。
转载请注明出处:
撰写人:伍华聪 http://HdhCmsTestiqidi测试数据
标签: 开发辅助
作者: Leo_wl
出处: http://HdhCmsTestcnblogs测试数据/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息