中国第一Ajax站长门户:www.okajax.com   虚拟主机 域名注册 云主机

XML序列化私有栏位 - okajax.com - Ajax中国

我要投稿 会员登陆 RSS订阅 本站推荐:
您的位置主页 > 网页编程 > .net > XML序列化私有栏位

XML序列化私有栏位

2009-05-03    文章来源:互联网    浏览次数:

假设今天有个Person的类别如下。除了名字、年龄、性别外,内含_friends清单用以提供IsFriend与AddFriend函式所须用到的朋友清单资料。

VB.NET

  1. Public Class Person  
  2.  
  3. #Region "Enum"  
  4.     Enum SexType  
  5.         Boy  
  6.         Girl  
  7.     End Enum 
  8. #End Region  
  9.  
  10.  
  11. #Region "Var"  
  12.     Private _name As String 
  13.     Private _year As Integer 
  14.     Private _sex As SexType  
  15.     Private _friendNames As New List(Of String)  
  16. #End Region  
  17.  
  18.  
  19. #Region "Property"  
  20.     Public Property Name() As String 
  21.         Get 
  22.             If String.IsNullOrEmpty(_name) Then 
  23.                 Return String.Empty  
  24.             End If 
  25.             Return _name  
  26.         End Get 
  27.         Set(ByVal value As String)  
  28.             _name = value  
  29.         End Set 
  30.     End Property 
  31.  
  32.     Public Property Year() As Integer 
  33.         Get 
  34.             Return _year  
  35.         End Get 
  36.         Set(ByVal value As Integer)  
  37.             _year = value  
  38.         End Set 
  39.     End Property 
  40.  
  41.     Public Property Sex() As SexType  
  42.         Get 
  43.             Return _sex  
  44.         End Get 
  45.         Set(ByVal value As SexType)  
  46.             _sex = value  
  47.         End Set 
  48.     End Property 
  49. #End Region  
  50.  
  51.  
  52. #Region "Public Method"  
  53.     Public Sub AddFriend(ByVal people As Person)  
  54.         _friendNames.Add(people.Name)  
  55.     End Sub 
  56.  
  57.     Public Function IsFriend(ByVal people As Person) As Boolean 
  58.         For Each friendName As String In _friendNames  
  59.             If friendName = people.Name Then 
  60.                 Return True 
  61.             End If 
  62.         Next 
  63.         Return False 
  64.     End Function 
  65. #End Region  
  66.  
  67.  
  68. End Class 

C#

  1. public class Person  
  2.     {  
  3.  
  4.         #region Enum  
  5.         public enum SexType  
  6.         {  
  7.             Boy,  
  8.             Girl  
  9.         }  
  10.         #endregion  
  11.  
  12.         #region Var  
  13.         private string _name;  
  14.         private int _year;  
  15.         private SexType _sex;  
  16.         private List<String> _friendNames = new List<String>();  
  17.         #endregion  
  18.  
  19.  
  20.         #region Property  
  21.         public string Name  
  22.         {  
  23.             get 
  24.             {  
  25.                 if (string.IsNullOrEmpty(_name))  
  26.                 {  
  27.                     return string.Empty;  
  28.                 }  
  29.                 return _name;  
  30.             }  
  31.             set { _name = value; }  
  32.         }  
  33.  
  34.         public int Year  
  35.         {  
  36.             get { return _year; }  
  37.             set { _year = value; }  
  38.         }  
  39.  
  40.         public SexType Sex  
  41.         {  
  42.             get { return _sex; }  
  43.             set { _sex = value; }  
  44.         }  
  45.         #endregion  
  46.  
  47.  
  48.         #region Public Method  
  49.         public void AddFriend(Person people)  
  50.         {  
  51.             _friendNames.Add(people.Name);  
  52.         }  
  53.  
  54.         public bool IsFriend(Person people)  
  55.         {  
  56.             foreach (String friendName in _friendNames)  
  57.             {  
  58.                 if (friendName == people.Name)  
  59.                 {  
  60.                     return true;  
  61.                 }  
  62.             }  
  63.             return false;  
  64.         }  
  65.         #endregion  
  66.  
  67.  
  68.     } 

在.NET程式里,若将该类别直接做XML序列化,则其类别的_friends这个私有的栏位资料将不会被序列化保存(因为.NET XML序列化无法序列化私有栏位资料) 。此时我们可以用自定义XML的方式来去解决此问题。透过自定义XML序列化,我们可以自己定义XML序列化的格式。也可以把本来不会序列化的私有栏位一并序列化。

但是,若只是很单纯的去实作自定义XML序列化。做出来的类别将无法与.NET本身的XML序列化做整合。举个例子来说,假设今天Person这个类别实作了自定义XML序列化。而程式中又有个PersonCollection这个类别内含Person这个类别成员。则此时,若PersonCollection这个类别没有实作自定义XML序列化,而想直接用来序列化的话。该程式在序列化时将会发生错误。也就是说,当A这个类别做了自定义XML序列化,而B这个类别的成员内含A这个类别时,则B通常也将需要自定义XML序列化。

要解决该问题,照着下面程式码片段的格式去实作自定义XML序列化即可。

VB.NET

  1. #Region "Implement IXmlSerializable"  
  2.     Public Function GetSchema() As System.Xml.Schema.XmlSchema Implements System.Xml.Serialization.IXmlSerializable.GetSchema  
  3.         Return Nothing 
  4.     End Function 
  5.  
  6.     Public Sub ReadXml(ByVal reader As System.Xml.XmlReader) Implements System.Xml.Serialization.IXmlSerializable.ReadXml  
  7.         Dim startElementName As String = reader.Name  
  8.         Dim currentElementName As String 
  9.  
  10.         Me._friendNames.Clear()  
  11.         Do 
  12.             currentElementName = reader.Name  
  13.             If currentElementName = startElementName AndAlso (reader.MoveToContent = Xml.XmlNodeType.EndElement OrElse reader.IsEmptyElement) Then 
  14.                 reader.Read()  
  15.                 Exit Do 
  16.             End If 
  17.  
  18.             Select Case currentElementName  
  19.                 Case "Name" 
  20.                     Me.Name = reader.ReadElementString()  
  21.  
  22.                 Case "Sex" 
  23.                     Me.Sex = CType(reader.ReadElementString(), SexType)  
  24.  
  25.                 Case "Year" 
  26.                     Me.Year = CInt(reader.ReadElementString())  
  27.  
  28.                 Case "Friend" 
  29.                     Me._friendNames.Add(reader.GetAttribute("Name"))  
  30.                     reader.Read()  
  31.                 Case Else 
  32.                     reader.Read()  
  33.  
  34.             End Select 
  35.  
  36.         Loop 
  37.     End Sub 
  38.  
  39.     Public Sub WriteXml(ByVal writer As System.Xml.XmlWriter) Implements System.Xml.Serialization.IXmlSerializable.WriteXml  
  40.         writer.WriteElementString("Name", Name)  
  41.         writer.WriteElementString("Sex"CInt(Sex).ToString)  
  42.         writer.WriteElementString("Year", Year.ToString)  
  43.         For Each friendName As String In _friendNames  
  44.             writer.WriteStartElement("Friend")  
  45.             writer.WriteAttributeString("Name", friendName)  
  46.             writer.WriteEndElement()  
  47.         Next 
  48.     End Sub 
  49. #End Region 

C#

  1. #region Implement IXmlSerializable   
  2.  
  3. public System.Xml.Schema.XmlSchema GetSchema()  
  4. {  
  5.     throw new NotImplementedException();  
  6. }  
  7.  
  8. public void ReadXml(System.Xml.XmlReader reader)  
  9. {  
  10.     string startElementName = reader.Name;  
  11.     string currentElementName;  
  12.  
  13.     this._friendNames.Clear();  
  14.     do 
  15.     {  
  16.         currentElementName = reader.Name;  
  17.         if (currentElementName == startElementName && (reader.MoveToContent() == System.Xml.XmlNodeType.EndElement || reader.IsEmptyElement))  
  18.         {  
  19.             reader.Read();  
  20.             break;   
  21.         }  
  22.  
  23.         switch (currentElementName)  
  24.         {  
  25.             case "Name":  
  26.                 this.Name = reader.ReadElementString();  
  27.                 break;  
  28.  
  29.             case "Sex":                          
  30.                 this.Sex = (SexType)int.Parse (reader.ReadElementString());  
  31.                 break;  
  32.  
  33.             case "Year":  
  34.                 this.Year = int.Parse(reader.ReadElementString());  
  35.                 break;  
  36.  
  37.             case "Friend":  
  38.                 this._friendNames.Add(reader.GetAttribute("Name"));  
  39.                 reader.Read();  
  40.                 break;  
  41.             default:  
  42.                 reader.Read();  
  43.                 break;  
  44.  
  45.         }  
  46.     }while (true);  
  47. }  
  48.  
  49. public void WriteXml(System.Xml.XmlWriter writer)  
  50. {  
  51.     writer.WriteElementString("Name", Name);  
  52.     writer.WriteElementString("Sex", ((int)Sex).ToString());  
  53.     writer.WriteElementString("Year", Year.ToString());  
  54.     foreach (string friendName in _friendNames)  
  55.     {  
  56.         writer.WriteStartElement("Friend");  
  57.         writer.WriteAttributeString("Name", friendName);  
  58.         writer.WriteEndElement();  
  59.     }  
  60. }  
  61.  
  62. #endregion 


 

其主要重点概念如下图所示:

image

文章评论(查看全部)

看不清楚?单击换一张。
loading.. 评论加载中....
关于我们 - 广告服务 - 版权隐私 - 免责声明 - RSS地图 - 网站地图 - 使用帮助 - 返回顶部