利用xml来存储一些像分类,文章评论之类的小数据的通用方法

来源:互联网 发布:网络位置可以删除吗 编辑:程序博客网 时间:2024/05/29 04:53

我们在做项目的时候经常会遇到分类,通常的做法是把分类放在数据库表里面,有没有什么好的办法做成通用的程序来存储这些类别呢?

我尝试了使用实体模型+反射+xml的方法来存储这些小数据;

具体过程是这样的,首先建立类别的实体模型这个大家再熟悉不过了

再一个就是写一个通用方法利用反射来操作xml文件

贴上利用反射操作xml代码供大家讨论,欢迎大家批评指正

using System;
using System.Collections.Generic;
using System.IO;
using System.Web.Hosting;
using System.Xml;
using System.Reflection;
using System.Xml.XPath;
using MS.Core.Domain.Common;
namespace MS.Data
{
    public class XmlDataContext<T> where T: class,new()
    {
        private readonly String _table;
        public XmlDataContext(String table){
            _table = table;
        }
        public XmlDataContext() { }
        #region
        public String XmlPath
        {
            get { return "~/App_Data/{0}.xml"; }
        }
        #endregion




        #region Utilities
        /// <summary>
        /// Maps a virtual path to a physical disk path.
        /// </summary>
        /// <param name="path">The path to map. E.g. "~/bin"</param>
        /// <returns>The physical path. E.g. "c:\inetpub\wwwroot\bin"</returns>
        private string MapPath(string path)
        {
            if (HostingEnvironment.IsHosted)
            {
                //hosted
                return HostingEnvironment.MapPath(path);
            }
            else
            {
                //not hosted. For example, run in unit tests
                string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
                path = path.Replace("~/", "").TrimStart('/').Replace('/', '\\');
                return Path.Combine(baseDirectory, path);
            }
        }
        private XmlElement CreateNewNode(XmlDocument doc,Type type,T entity)
        {
            String fileName = String.IsNullOrWhiteSpace(_table) ? type.Name : _table;
            //创建子元素
            XmlElement newNode = doc.CreateElement(fileName);
            //设置属性ID
            PropertyInfo pId = type.GetProperty("Id");
            newNode.SetAttribute("Id", pId.GetValue(entity, null).ToString());




            foreach (var property in type.GetProperties())
            {
                String propertyName = property.Name;
                if (propertyName != "Id")
                {
                    XmlElement newInnerNode = doc.CreateElement(propertyName);
                    


                    object temp = property.GetValue(entity, null);
                    if (temp != null)
                        newInnerNode.InnerText = temp.ToString();
                    else
                        newInnerNode.InnerText = "";


                    newNode.AppendChild(newInnerNode);
                }
            }
            return newNode;
        }
        #endregion


        public  void Insert(T entity)
        {


            var type = entity.GetType();
            String fileName = String.IsNullOrWhiteSpace(_table) ? type.Name : _table;
            String filePath = String.Format(XmlPath, fileName);
            if (File.Exists(MapPath(filePath)))
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(MapPath(filePath));


                doc.DocumentElement.AppendChild(CreateNewNode(doc,type,entity));
                doc.Save(MapPath(filePath));
               
            }
            else
            {
                XmlDocument doc = new XmlDocument();
                XmlDeclaration newDec = doc.CreateXmlDeclaration("1.0", null, null);
                doc.AppendChild(newDec);
                //创建根
                XmlElement newRoot = doc.CreateElement(String.Format("{0}Root", fileName));
   
                newRoot.AppendChild(CreateNewNode(doc, type, entity));
                doc.AppendChild(newRoot);
                XmlTextWriter xtw = new XmlTextWriter(MapPath(filePath), null);
                xtw.Formatting = Formatting.Indented;
                doc.WriteContentTo(xtw);
                xtw.Close();


                
            }
        }


        public void Update(T entity)
        {
            var type = entity.GetType();
            String fileName = String.IsNullOrWhiteSpace(_table) ? type.Name : _table;
            String filePath = String.Format(XmlPath, fileName);
            if (File.Exists(MapPath(filePath)))
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(MapPath(filePath));
                String xpath = String.Format("/{0}Root/{0}", fileName);
                XmlNodeList xmlNodeList=doc.SelectNodes(xpath);
                foreach (XmlNode xmlNode in xmlNodeList) 
                {
                    String id = xmlNode.Attributes["Id"].Value;
                    PropertyInfo pId = type.GetProperty("Id");
                    if (id == pId.GetValue(entity, null).ToString())
                    { 
                        //修改其它元素
                        foreach (var property in type.GetProperties())
                        {
                            String propertyName = property.Name;
                            if (propertyName != "Id")
                            {
                                XmlNode innerXmlNode=  xmlNode.SelectSingleNode(propertyName);
                                PropertyInfo pPropertyInfo = type.GetProperty(propertyName);
                                object temp = pPropertyInfo.GetValue(entity, null);
                                if (temp != null)
                                    innerXmlNode.InnerText = temp.ToString();
                                else
                                    innerXmlNode.InnerText = "";
                                
                            }
                        }
                    }
                }
                
                doc.Save(MapPath(filePath));


            }
        }


        public void Delete(String id)
        {
            var type = typeof(T);
            String fileName = String.IsNullOrWhiteSpace(_table) ? type.Name : _table;
            String filePath = String.Format(XmlPath, fileName);
            if (File.Exists(MapPath(filePath)))
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(MapPath(filePath));
                String xpath = String.Format("/{0}Root/{0}", fileName);
                XmlNodeList xmlNodeList = doc.SelectNodes(xpath);
                foreach (XmlNode xmlNode in xmlNodeList)
                {
                    String attId = xmlNode.Attributes["Id"].Value;
                    if (attId == id)
                    {
                        doc.DocumentElement.RemoveChild(xmlNode);
                    }
                }


                doc.Save(MapPath(filePath));


            }
        }


        public T Get(String id) 
        {


            String fileName = String.IsNullOrWhiteSpace(_table) ? typeof(T).Name : _table;
            String filePath = String.Format(XmlPath, fileName);
            if (File.Exists(MapPath(filePath)))
            {
                T entity = new T();
                XPathDocument doc = new XPathDocument(MapPath(filePath));
                XPathNavigator nav = ((IXPathNavigable)doc).CreateNavigator();
                XPathNodeIterator iter = nav.Select(String.Format("/{0}Root/{0}", fileName));
                while (iter.MoveNext())
                {
                    XPathNodeIterator newIter = iter.Current.SelectDescendants(XPathNodeType.Element, false);


                    if (iter.Current.GetAttribute("Id", "") == id)
                    {


                        if (entity.GetType().GetProperty("Id").PropertyType == typeof(Int32))
                            entity.GetType().GetProperty("Id").SetValue(entity, int.Parse(id));
                        else
                            entity.GetType().GetProperty("Id").SetValue(entity, id);




                        while (newIter.MoveNext())
                        {
                            String propertyType = entity.GetType().GetProperty(newIter.Current.Name).PropertyType.ToString();
                            var type = entity.GetType().GetProperty(newIter.Current.Name).PropertyType;
                            switch (propertyType)
                            {
                                case "System.Int32": entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, int.Parse(newIter.Current.Value)); break;
                                case "System.DateTime": entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, DateTime.Parse(newIter.Current.Value)); break;
                                case "System.Boolean": entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, bool.Parse(newIter.Current.Value)); break;
                                case "System.Decimal": entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, Decimal.Parse(newIter.Current.Value)); break;
                                case "Tenda.Core.Domain.Common.SelectionModeEnum":


                                    entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, (SelectionModeEnum)Enum.Parse(type, newIter.Current.Value, true)); break;
                                case "Tenda.Core.Domain.Common.ListModeEnum":


                                    entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, (ListModeEnum)Enum.Parse(type, newIter.Current.Value, true)); break;
                                case "Tenda.Core.Domain.Common.DefaultValueEnum":


                                    entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, (DefaultValueEnum)Enum.Parse(type, newIter.Current.Value, true)); break;
                                case "Tenda.Core.Domain.Common.FieldTypeEnum":


                                    entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, (FieldTypeEnum)Enum.Parse(type, newIter.Current.Value, true)); break;
                                default: entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, newIter.Current.Value); break;
                            }
                        }
                        break;
                    }
                }


                return entity;
            }
            else
            {
                return null;
            }
           
        }




        public List<T> GetAll()
        {
            List<T> list = new List<T>();
            String fileName =String.IsNullOrWhiteSpace(_table)? typeof(T).Name:_table;
            String filePath = String.Format(XmlPath, fileName);
            if (File.Exists(MapPath(filePath)))
            {
                XPathDocument doc = new XPathDocument(MapPath(filePath));
                XPathNavigator nav = ((IXPathNavigable)doc).CreateNavigator();
                XPathNodeIterator iter = nav.Select(String.Format("/{0}Root/{0}", fileName));
                while (iter.MoveNext())
                {
                    T entity = new T();
                    if (entity.GetType().GetProperty("Id").PropertyType == typeof(Int32))
                        entity.GetType().GetProperty("Id").SetValue(entity, int.Parse(iter.Current.GetAttribute("Id", "")));
                    else
                        entity.GetType().GetProperty("Id").SetValue(entity, iter.Current.GetAttribute("Id", ""));
                    XPathNodeIterator newIter = iter.Current.SelectDescendants(XPathNodeType.Element, false);
                    while (newIter.MoveNext())
                    {
                        String propertyType=  entity.GetType().GetProperty(newIter.Current.Name).PropertyType.ToString();
                        var type = entity.GetType().GetProperty(newIter.Current.Name).PropertyType;
                        switch (propertyType)
                        {
                            case "System.Int32": entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, int.Parse(newIter.Current.Value)); break;
                            case "System.DateTime": entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, DateTime.Parse(newIter.Current.Value)); break;
                            case "System.Boolean": entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, bool.Parse(newIter.Current.Value)); break;
                            case "System.Decimal": entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, Decimal.Parse(newIter.Current.Value)); break;
                            case "Tenda.Core.Domain.Common.SelectionModeEnum":


                                entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, (SelectionModeEnum)Enum.Parse(type, newIter.Current.Value, true)); break;
                            case "Tenda.Core.Domain.Common.ListModeEnum":


                                entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, (ListModeEnum)Enum.Parse(type, newIter.Current.Value, true)); break;
                            case "Tenda.Core.Domain.Common.DefaultValueEnum":


                                entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, (DefaultValueEnum)Enum.Parse(type, newIter.Current.Value, true)); break;
                            case "Tenda.Core.Domain.Common.FieldTypeEnum":


                                entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, (FieldTypeEnum)Enum.Parse(type, newIter.Current.Value, true)); break;
                            default: entity.GetType().GetProperty(newIter.Current.Name).SetValue(entity, newIter.Current.Value); break;
                        }
                        
                    }
                    list.Add(entity);




                }
            }
            
            return list;
        }
    }
}

0 0