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

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

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

    public static voidRunSnippet()
{
XmlDocument xmldoc
= newXmlDocument ( ) ;
    
//加入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, objectobj, Type type)
{
XmlSerializerNamespaces ns
= newXmlSerializerNamespaces();
ns.Add(
"", "");try{//如果文件目录不存在,那么创建目录 if (!File.Exists(path))
{
FileInfo fi
= newFileInfo(path);if (!fi.Directory.Exists)
{
Directory.CreateDirectory(fi.Directory.FullName);
}
}
using (Stream stream = newFileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
{
XmlSerializer format
= newXmlSerializer(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(stringpath, Type type)
{
try{using (Stream stream = newFileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
XmlSerializer formatter
= newXmlSerializer(type);
stream.Seek(
0, SeekOrigin.Begin);object obj =formatter.Deserialize(stream);
stream.Close();
returnobj;
}
}
catch{return null;
}
}

注意其中代码

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

ns.Add("", "");

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

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

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

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

       private void btnUserNormal_Click(objectsender, EventArgs e)
{
DataOfUser obj
= newDataOfUser();
UserInfo user
= newUserInfo();
user.ID
=Guid.NewGuid().ToString();
user.Sex
= "";
user.UserName
= "张三";
user.UserNo
= "20010001";
user.Birthday
= "1999-1-1";
obj.list.Add(user);

user
= newUserInfo();
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, objectobj, Type type)
{
XmlSerializerNamespaces ns
= newXmlSerializerNamespaces();
ns.Add(
"", "");try{if (!File.Exists(path))
{
FileInfo fi
= newFileInfo(path);if (!fi.Directory.Exists)
{
Directory.CreateDirectory(fi.Directory.FullName);
}
}
using (Stream stream = newFileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
{
string content = "";using(MemoryStream ms = newMemoryStream())
{
XmlSerializer format
= newXmlSerializer(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(stringpath, 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 = newMemoryStream(bytes))
{
XmlSerializer formatter
= newXmlSerializer(type);

stream.Seek(
0, SeekOrigin.Begin);object obj =formatter.Deserialize(stream);
stream.Close();
returnobj;
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}

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

        private void btnUserEncrypt_Click(objectsender, EventArgs e)
{
DataOfUser obj
= newDataOfUser();
UserInfo user
= newUserInfo();
user.ID
=Guid.NewGuid().ToString();
user.Sex
= "";
user.UserName
= "张三";
user.UserNo
= "20010001";
user.Birthday
= "1999-1-1";
obj.list.Add(user);

user
= newUserInfo();
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(objectsender, EventArgs e)
{
string file =FileDialogHelper.OpenFile();if (!string.IsNullOrEmpty(file))
{
DataOfUser info
= XmlDeserializeDecrypt(file, typeof(DataOfUser)) asDataOfUser;if (info != null)
{
MessageUtil.ShowTips(
"OK");
}
}
}

标签: none

添加新评论