zoukankan      html  css  js  c++  java
  • 用于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是私有的,不过粘贴时也能正常工作。

  • 相关阅读:
    《神经网络设计》读书笔记第一章
    <转>How to Encourage Your Child's Interest in Science and Tech
    <转>卷积神经网络是如何学习到平移不变的特征
    卷积神经网络物体检测之感受野大小计算
    神经网络向量化求反向传播梯度
    SSD框架训练自己的数据集
    object detect links
    Computer vision labs
    Deep Learning Blog lists
    YOLO: Real-Time Object Detection
  • 原文地址:https://www.cnblogs.com/pcy0/p/DotNetEx_XmlFormater.html
Copyright © 2011-2022 走看看