用于XML格式存储的工具类

最近很喜欢使用XML(C#的Linq to XML)。写个类后总想把它能用XML文件保存起来,一般我都是写个ToXElement函数然后在里面……

今天写烦了,想写一个通用的工具类,以便很方便地把一个类保存化为XML。

看看写出来的结果:

  1  /* ***********************************************************************\
  2   * 把一个对象格式化为XML(元素),即:
  3   *     1、该XML元素的名字为该对象的类型
  4   *     2、对该对象中每一个公共属性(Property)转换为字符串(String)
  5   *         保存到XML元素的属性中
  6   * 把一个XML粘贴到一个对象中,即为上一过程的逆过程。
  7   *     
  8   * 对象信息保存到XML中(然后再保存到文件)很显然将具有很高的可读性
  9  \*********************************************************************** */
 10  using  System;
 11  using  System.Collections.Generic;
 12  using  System.Linq;
 13  using  System.Text;
 14  using  System.Xml.Linq;
 15  namespace  DotNetEx.FormatAsXml
 16  {
 17       ///   <summary>
 18       ///  标识能格式化为XML,可以被用在类和结构上,不可以继承,不支持多重标记
 19       ///   </summary>
 20      [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited  =   false
 21          AllowMultiple  =   false )]
 22       public   sealed   class  CanFormatToXmlAttribute : Attribute
 23      {
 24          public  CanFormatToXmlAttribute () {   }
 25      }
 26       ///   <summary>
 27       ///  标识该属性不用被格式化
 28       ///   </summary>
 29      [AttributeUsage(AttributeTargets.Property,Inherited = false ,
 30          AllowMultiple = false )]
 31       public   sealed   class  DonotFormatToXmlAttribute:Attribute
 32      {
 33           public  DonotFormatToXmlAttribute(){}
 34      }
 35       ///   <summary>
 36       ///  格式化为XML的格式器
 37       ///   </summary>
 38       public   static   class  XmlFormater
 39      {
 40           ///   <summary>
 41           ///  把一个对象格式化为XML,这个对象必须有CanFormatToXml属性(Attribute)
 42           ///   </summary>
 43           ///   <param name="o"> 要格式的对象 </param>
 44           ///   <returns> 格式化的XML元素 </returns>
 45           ///   <exception type="UnsurportedTypeException"> 输入的对象的类型必须是支持格式化为XML的类型(有CanFormatToXml属性) </exception>
 46           ///   <exception type="ArgumentNullException"> 输入的对象不能为NULL </exception>
 47           public   static  XElement ToXElement( object  o){
 48               if (o == null ){
 49                   throw   new  ArgumentNullException( " o " );
 50              }
 51              Type t = o.GetType();
 52              var atts =  t.GetCustomAttributes( typeof (CanFormatToXmlAttribute), false );
 53              
 54               if (atts.Length == 0 ){
 55                   throw   new  UnsurportedTypeException(t);
 56              }
 57              XElement xml = new  XElement(t.Name);
 58              var propertyInfos = t.GetProperties();
 59               foreach  (var proi  in  propertyInfos) {
 60                   if (proi.CanRead){
 61                       if (proi.GetCustomAttributes( typeof (DonotFormatToXmlAttribute), false )
 62                          .Length == 0 ){
 63                          var pg  =  proi.GetGetMethod();
 64                           object  ret  =  pg.Invoke(o,  null );
 65                          xml.Add( new  XAttribute(proi.Name, Convert.ChangeType(ret,  typeof ( string ))));
 66                      }
 67                  }
 68              }
 69               return  xml;
 70          }
 71           ///   <summary>
 72           ///  从一个格式化好的XML中粘贴相关格式化信息到对象
 73           ///   </summary>
 74           ///   <param name="xml"> 输入的格式化好的XML </param>
 75           ///   <param name="obj"> 一个目标对象,其必须支持格式化为XML(有CanFormatToXml属性) </param>
 76           public   static   void  Pase(XElement xml,  object  obj){
 77               if  (xml  ==   null ) {
 78                   throw   new  ArgumentNullException( " xml " );
 79              }
 80              
 81               if (obj == null ){
 82                   throw   new  ArgumentNullException( " obj " );
 83              }
 84 
 85              Type type  =  obj.GetType();
 86               if  (( type.GetCustomAttributes( typeof (CanFormatToXmlAttribute),  false )
 87                      .Length  ==   0  )  ||
 88                  xml.Name != type.Name
 89                  ) {
 90                   throw   new  UnsurportedTypeException(type);
 91              }
 92              
 93              var pis  =  type.GetProperties();
 94               foreach  (var pi  in  pis) {
 95                   if (pi.CanWrite){
 96                       if (pi.GetCustomAttributes( typeof (DonotFormatToXmlAttribute), false )
 97                          .Length == 0 ){
 98                          var psm  =  pi.GetSetMethod( true );
 99                          psm.Invoke(obj,
100                               new   object []{ Convert.ChangeType(
101                                  xml.Attribute(pi.Name).Value,
102                                  pi.PropertyType)}
103                                  );
104                      }
105                  }
106              }
107          }
108           ///   <summary>
109           ///  不是支持格式化为XML(有CanFormatToXml属性)的类型
110           ///   </summary>
111           public   sealed   class  UnsurportedTypeException:Exception
112          {
113               public  UnsurportedTypeException(Type t){
114                  Type = t;
115              }
116               public  Type Type{
117                   private   set ;
118                   get ;
119              }
120               public   override   string   Message
121              {
122                get  
123               { 
124                  return   " 类型\ "" +Type+ " \ " 不支持格式化为XML " ;
125               }
126              }
127          }
128      }
129     //
130       static   class  Test
131      {
132          [CanFormatToXml()]
133           class  Person{
134               public  Person(String name ){
135                  Name  =  name;
136              }
137               public   string  Name{
138                   get ;
139                   private   set ;
140              }
141               public   int  Age{
142                   get ;
143                   set ;
144              }
145               public  DateTime BirthDay {
146                   get ;
147                   set ;
148              }
149              [DonotFormatToXml()]
150               public  Person Test{
151                   get ;
152                   set ;
153              }
154          }
155           static   void  Main(){
156              Person p = new  Person( " Hack " ){
157                  BirthDay = new  DateTime( 1990 , 1 , 1 ),
158                  Age = 19 ,
159                  Test = new  Person( " Test " ){
160                      Age = 20
161                  }
162              };
163              var x = XmlFormater.ToXElement(p);
164              Console.WriteLine(x.ToString());
165              x.Attribute( " Name " ).Value  =   " Changed " ;
166              XmlFormater.Pase(x, p);
167              Console.WriteLine(XmlFormater.ToXElement(p).ToString());
168          }
169      }
170      // */
171  }
172 
173 

 

那个静态类Test是用于测试的,测试结果:

<Person Name="Hack" Age="19" BirthDay="1990/1/1 0:00:00" />
<Person Name="Changed" Age="19" BirthDay="1990/1/1 0:00:00" />

还不错,能把一个对象的公有属性都写到XML元素中,反过来也能粘贴回对象。

原理分析:(代码很短很清晰,这里就不多说了)

       从对象格式化到XML时,使用反射从Type得到属性信息,再得到属性的Getter,然后调用就行了;反过来也差不多。

注意那个Person.Name属性,它的Setter是私有的,不过粘贴时也能正常工作。

 

转载于:https://www.cnblogs.com/pcy0/archive/2009/12/12/DotNetEx_XmlFormater.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值