zoukankan      html  css  js  c++  java
  • C#实体映射XML操作

    在我的项目有一些xml数据(格式如下)

    代码
     1 <?xml version="1.0" encoding="utf-8"?>
     2 <Config>
     3   <FeatureType>
     4     <Item ID="1" Name="外型材质" Image="外型材质特征用到的图片" Order="2" />
     5     <Item ID="2" Name="拍照功能" Image="特征用到的图片" Order="2" />
     6   </FeatureType>
     7   <OSType>
     8     <Item ID="1" Name="Windows Mobile Professional" />
     9     <Item ID="2" Name="Windows Mobile Standard" />
    10     <Item ID="3" Name="Linux" />
    11     <Item ID="4" Name="其它" />
    12     <Item ID="5" Name="Andriod" />
    13   </OSType>
    14 </Config>

    以前的处理方式是这样:

    1.建立相应实体类

    例:类FeatureType对应一个FeatureType结点下一个实体

    public class FeatureType
    {
        
    public int ID { getset; }
        
    public string Name { getset; }
    }

    2.写一个FeatureType的管理类来处理如(添加,删除,更新,取列表,取单个)等操作

         这样问题就来了:如果是少量的xml文档或结点组(例如<FeatureType>,<OSType>),处理起来还算轻松,可现在有很多这样的文档或结点组,而且我还想以强类型实体的形式来访问处理..........那就写吧。

    我的处理方法是这样的,欢迎大家指正!

    首先需要两个特性类:

    CacheEntityAttribute
    [AttributeUsage(AttributeTargets.Class,AllowMultiple=false,Inherited=true)] 
        
    public class CacheEntityAttribute : Attribute
        {
            
    //public string ConfigPath { get; set; }
            public string SectionName { getset; }
            
    public string ElementName { getset; }

            
    public CacheEntityAttribute(string sectionName, string elementName)
            {
                
    //this.ConfigPath = configPath;
                this.SectionName = sectionName;
                
    this.ElementName = elementName;
            }
        }
    CacheEntityPropertyAttribute
    [AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=true)]
        
    public class CacheEntityPropertyAttribute : Attribute
        {
            
    public string PropertyName { getset; }
            
    public Type DateType { getset; }
            
    public bool IsPrimaryKey { getset; }

            
    public CacheEntityPropertyAttribute(string propertyName, Type dataType,bool isPrimaryKey)
            {
                
    this.PropertyName = propertyName;
                
    this.DateType = dataType;
                
    this.IsPrimaryKey = isPrimaryKey;
            }

            
    public CacheEntityPropertyAttribute(string propertyName, Type dataType) :
                
    this(propertyName,dataType,false)
            {}
        }

    CacheEntityAttribute:描述实体类对应的结点名称及要处理的xml原素名称(应用于类)

    CacheEntityPropertyAttribute:描述实体字段对应的xml结点属性信息(应用于属性)

     实体基类:

    CacheEntityBase
    public abstract class CacheEntityBase
        {
            [CacheEntityProperty(
    "ID"typeof(int),true)]
            
    public int ID { getset; }

            [CacheEntityProperty(
    "Name"typeof(string),true)]
            
    public string Name { getset; }
        }

    新的FeatureType类

    FeatureType
    [CacheEntity("FeatureType""Item")]
        
    public class FeatureType : CacheEntityBase
        {
            [CacheEntityProperty(
    "Image",typeof(string))]
            
    public string Image { getset; }

            [CacheEntityProperty(
    "Order",typeof(int))]
            
    public int Order { getset; }

            
    public FeatureType(int id, string name, string image, int order)
            {
                
    this.ID = id;
                
    this.Name = name;
                
    this.Image = image;
                
    this.Order = order;
            }

            
    public FeatureType() { }
        }

     CacheEntityManager类:

    这个类型中有一些范型方法(如,更新,添加等),核心就是通过反射来处理相关操作

    CacheEntityManager
    public class CacheEntityManager
        {
            
    public string ConfigPath { getset; }
            
    private XmlDocument xdt;
            
    public string RootElement { getset; }

            
    public CacheEntityManager(string configPath,string rootElement)
            {
                
    this.ConfigPath = configPath;
                
    this.RootElement = rootElement;
                
    this.xdt = new XmlDocument();
                
    this.xdt.Load(ConfigPath);
            }

            
    /// <summary>
            
    /// 根据ID,加载单个实体
            
    /// </summary>
            
    /// <typeparam name="T"></typeparam>
            
    /// <param name="id"></param>
            
    /// <returns></returns>
            public T LoadSingle<T>(int id) where T : CacheEntityBase
            {
                CacheEntityAttribute eAttr 
    =
                    TypeHelper.LoadLastAttribute
    <CacheEntityAttribute>(typeof(T), true);
                
    string xpath = "/" + this.RootElement + "/" + eAttr.SectionName + "/" + eAttr.ElementName;
                xpath 
    += "[@ID=" + id.ToString() + "]";
                
                XmlNode node 
    = this.xdt.SelectSingleNode(xpath);
                
    return createInstance<T>(node);
                
            }

            
    public void Remove<T>(int id) where T : CacheEntityBase
            {
                CacheEntityAttribute eAttr 
    = 
                    TypeHelper.LoadLastAttribute
    <CacheEntityAttribute>(typeof(T), true);
                
    string xpath = "/" + this.RootElement + "/" + eAttr.SectionName + "/" + eAttr.ElementName;
                xpath 
    += "[@ID=" + id.ToString() + "]";
                XmlNodeList nodeList 
    = this.xdt.SelectNodes(xpath);
                
    if (nodeList.Count > 0)
                {
                    
    for (int i = 0; i < nodeList.Count; i++)
                    {
                        nodeList[i].ParentNode.RemoveChild(nodeList[i]);
                    }
                    
    this.xdt.Save(this.ConfigPath);
                }
            }

            
    private T createInstance<T>(XmlNode node)
            {
                
    if (node == null)
                {
                    
    return default(T);
                }
                
    else
                {
                    List
    <CacheEntityPropertyAttribute> attrs =
                        TypeHelper.LoadPropertyAttribute
    <CacheEntityPropertyAttribute>(typeof(T));
                    
                    T obj 
    = (T)Activator.CreateInstance<T>();
                    Type objType 
    = typeof(T);
                    
    for (int i = 0; i < attrs.Count; i++)
                    {
                        XmlAttribute xmlAttr 
    = getAttribute(node, attrs[i].PropertyName);
                        
    try
                        {              
                            Type fType 
    = attrs[i].DateType;
                            
    object value;
                            
    if (fType.IsValueType)
                            {
                                value 
    = TypeHelper.Parse(fType, xmlAttr.Value);
                            }
                            
    else
                            {
                                value 
    = xmlAttr.Value;
                            }
                            objType.GetProperty(attrs[i].PropertyName).SetValue(obj,
                                value,
    null);
                        }
                        
    catch{}
                    }
                    
    return obj;
                }
            }

            
    private XmlAttribute getAttribute(XmlNode node,string attrName)
            {
                
    try
                {
                    
    return node.Attributes[attrName];
                }
                
    catch
                {
                    
    return null;
                }
            }

            
    /// <summary>
            
    /// 加载全部
            
    /// </summary>
            
    /// <param name="filter"></param>
            
    /// <returns></returns>
            public List<T> LoadList<T>() where T : CacheEntityBase
            {
                List
    <T> list = new List<T>();
                CacheEntityAttribute eAttr 
    =
                    AttributeHelper.LoadLastAttribute
    <CacheEntityAttribute>(typeof(T), true);
                
    string xpath = "/" + this.RootElement + "/" + eAttr.SectionName + "/" + eAttr.ElementName;
                XmlNodeList nodes 
    = this.xdt.SelectNodes(xpath);
                
    foreach (XmlNode node in nodes)
                {
                    T obj 
    = this.createInstance<T>(node);
                    
    if (obj != null) list.Add(obj);
                }
                
    return list;
            }

            
    /// <summary>
            
    /// 持久化
            
    /// </summary>
            
    /// <typeparam name="T"></typeparam>
            
    /// <param name="entity"></param>
            public void Insert<T>(T entity) where T : CacheEntityBase
            {
                CacheEntityAttribute eAttr 
    =
                    AttributeHelper.LoadLastAttribute
    <CacheEntityAttribute>(typeof(T), true);
                List
    <CacheEntityPropertyAttribute> attrs =
                        TypeHelper.LoadPropertyAttribute
    <CacheEntityPropertyAttribute>(typeof(T));
                
    string xpath = "/" + this.RootElement + "/" + eAttr.SectionName + "/" + eAttr.ElementName;
                
    string temp = xpath + "[@Name='" + TypeHelper.GetPropertyValue(entity, "Name"+ "']/@Name";
                XmlNode n 
    = this.xdt.SelectSingleNode(temp);

                
    if (n != nullreturn;
                XmlElement elm 
    = this.xdt.CreateElement(eAttr.ElementName);
                
    foreach (CacheEntityPropertyAttribute attr in attrs)
                {
                    XmlAttribute xa 
    = this.xdt.CreateAttribute(attr.PropertyName);
                    xa.Value 
    = TypeHelper.GetPropertyValue(entity, attr.PropertyName).ToString();
                    elm.Attributes.Append(xa);
                }
                
    this.xdt.SelectSingleNode("/" + this.RootElement + "/" + eAttr.SectionName).AppendChild(elm);
                
    this.xdt.Save(this.ConfigPath);
            }

            
    /// <summary>
            
    /// 更新
            
    /// </summary>
            
    /// <typeparam name="T"></typeparam>
            
    /// <param name="entity"></param>
            public void Update<T>(T entity) where T : CacheEntityBase
            {
                CacheEntityAttribute eAttr 
    =
                    AttributeHelper.LoadLastAttribute
    <CacheEntityAttribute>(typeof(T), true);
                List
    <CacheEntityPropertyAttribute> attrs =
                        TypeHelper.LoadPropertyAttribute
    <CacheEntityPropertyAttribute>(typeof(T));
                
    string xpath = "/" + this.RootElement + "/" + eAttr.SectionName ;
                
    string temp = xpath + "/" + eAttr.ElementName +
                    
    "[@Name='" + TypeHelper.GetPropertyValue(entity, "Name").ToString() + "'][@ID!=" +
                    TypeHelper.GetPropertyValue(entity, 
    "ID").ToString() + "]/@Name";
                XmlNode n 
    = this.xdt.SelectSingleNode(temp);
                
    if (n != nullreturn;
                xpath 
    += "/" + eAttr.ElementName + "[@ID=" + TypeHelper.GetPropertyValue(entity, "ID"+ "]";
                
    string str2;
                
    foreach (CacheEntityPropertyAttribute attr in attrs)
                {
                    str2 
    = xpath + "/@" + attr.PropertyName;
                    XmlNode node 
    = this.xdt.SelectSingleNode(str2);
                    node.InnerText 
    = TypeHelper.GetPropertyValue(entity, attr.PropertyName).ToString();
                    
    this.xdt.Save(this.ConfigPath);
                }

            }

        }

    这个类还有一些问题没有处理,就是对主键的处理,相关的条件判断我是直接在类里面,需要后续版本会做相应处理.

    首先不管理处理的好坏,感觉自已对反射的认识更深了一步!

    还有就是处理String To ValueType类型时想了好久也没有解决办法,最后还是google了,原来可以Relection值类型的静态方法(Parse),哈哈,晕了半天

    文章写的烂,您凑合着看!不爽请拍砖!

  • 相关阅读:
    如何通过CSS3实现背景图片色彩的梯度渐变
    提升网站页面打开速度的12个建议
    DIV+CSS高手必知的15个CSS常识
    飞机订票-1注册用户脚本
    需求不明的测试
    职业发展-外包公司考虑项
    Linux-Apache+Mysql+PHP+PHPWind(重点Apache+PHP集成环境)
    LR11-更改licence
    Linux-服务排查
    C语言-删除重复字符
  • 原文地址:https://www.cnblogs.com/byxxw/p/1644256.html
Copyright © 2011-2022 走看看