发布一个简单实用的xml文件操作帮助类

自己根据网上资料和自己的项目实践整理了一个比较实用的操作xml文件的帮助类,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Xml;
using System.Xml.Linq;

namespace DotNet.Common.Util
{
    /// <summary>
    /// xml文件操作帮助类
    /// </summary>
    public static class XmlHelper<T> where T : class, new()
    {
        #region  查询

        /// <summary>
        /// 一次性取出所有记录
        /// </summary>
        /// <param name="xmlPath">xml路径</param>
        /// <param name="rootName">根节点名</param>
        /// <param name="eleName">元素名</param>
        /// <returns></returns>
        public static List<T> GetObject(string xmlPath, string rootName, string eleName)
        {
            if (string.IsNullOrEmpty(xmlPath))
            {
                throw new Exception("xml文件路径为空");
            }

            try
            {
                XDocument xmlDoc = XDocument.Load(xmlPath);
                List<XElement> listElements = null;
                var query =
                    from list in xmlDoc.Element(rootName).Elements(eleName)
                    select list;
                listElements = query.ToList<XElement>();

                List<T> listT = new List<T>();
                if (listElements != null && listElements.Count > 0)
                {
                    foreach (XElement item in listElements)
                    {
                        T objT = new T();
                        BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;//反射标示
                        Type objTType = objT.GetType(); //通过反射绑定属性
                        foreach (PropertyInfo pi in objTType.GetProperties(bf))
                        {
                            foreach (XAttribute att in item.Attributes())
                            {
                                if (pi.Name.ToUpper() == att.Name.ToString().ToUpper())
                                {
                                    object value = att.Value;

                                    try
                                    {
                                        object realValue = null;
                                        if (pi.PropertyType.Equals(typeof(Nullable<Int32>))) //泛型可空类型 
                                        {
                                            if (value != null)
                                            {
                                                if (string.IsNullOrEmpty(value.ToString()))
                                                {
                                                    realValue = null;
                                                }
                                                else
                                                {
                                                    realValue = int.Parse(value.ToString());
                                                }
                                            }
                                        }
                                        else if (pi.PropertyType.Equals(typeof(Nullable<Int64>))) //泛型可空类型 
                                        {
                                            if (value != null)
                                            {
                                                if (string.IsNullOrEmpty(value.ToString()))
                                                {
                                                    realValue = null;
                                                }
                                                else
                                                {
                                                    realValue = int.Parse(value.ToString());
                                                }
                                            }
                                        }
                                        else if (pi.PropertyType.Equals(typeof(Nullable<DateTime>))) //泛型可空类型 
                                        {
                                            if (value != null)
                                            {
                                                if (string.IsNullOrEmpty(value.ToString()))
                                                {
                                                    realValue = null;
                                                }
                                                else
                                                {
                                                    realValue = DateTime.Parse(value.ToString());
                                                }
                                            }
                                        }
                                        else if (pi.PropertyType.Equals(typeof(Nullable<Boolean>))) //泛型可空类型 
                                        {
                                            if (value != null)
                                            {
                                                if (string.IsNullOrEmpty(value.ToString()))
                                                {
                                                    realValue = null;
                                                }
                                                else
                                                {
                                                    realValue = Boolean.Parse(value.ToString());
                                                }
                                            }
                                        }
                                        else if (pi.PropertyType.Equals(typeof(Nullable))) //可空类型 
                                        {
                                            realValue = value;
                                        }
                                        else
                                        {
                                            try
                                            {
                                                realValue = Convert.ChangeType(value, pi.PropertyType);
                                            }
                                            catch
                                            {
                                                realValue = null;
                                            }
                                        }
                                        pi.SetValue(objT, realValue, null);
                                    }
                                    catch (FormatException fex)
                                    {
                                        throw fex;
                                    }
                                    catch (Exception ex)
                                    {
                                        throw ex;
                                    }
                                    break;
                                }
                            }
                        }
                        listT.Add(objT);
                    }
                }
                return listT;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 根据查询条件取得匹配所有条件的结果集
        /// </summary>
        /// <param name="xmlPath"></param>
        /// <param name="rootName"></param>
        /// <param name="eleName"></param>
        /// <param name="searchCondition">查询条件对象</param>
        /// <returns></returns>
        public static List<T> GetObject(string xmlPath, string rootName, string eleName, T searchCondition)
        {
            List<T> listT = GetObject(xmlPath, rootName, eleName);
            List<T> listTResult = new List<T>();
            foreach (T item in listT)
            {
                CompareTByCondition(item, searchCondition, listTResult);
            }
            return listTResult;
        }

        /// <summary>
        ///  匹配比较查询条件(没有iBATIS方便 ,通过反射)
        /// </summary>
        /// <param name="item"></param>
        /// <param name="searchCondition"></param>
        /// <param name="listT"></param>
        public static void CompareTByCondition(T item, T searchCondition, List<T> listT)
        {
            bool flag = true;
            BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;//反射标示
            Type objTSearchType = searchCondition.GetType();
            Type objTSourceType = item.GetType();
            //通过反射绑定父级属性
            foreach (PropertyInfo pi in objTSearchType.GetProperties(bf))
            {
                object searchValue = pi.GetValue(searchCondition, null);
                if (searchValue == null)
                {
                    continue;
                }
                if (string.IsNullOrEmpty(searchValue.ToString()))
                {
                    continue;
                }

                foreach (PropertyInfo piSource in objTSourceType.GetProperties(bf))
                {
                    if (string.Compare(pi.Name, piSource.Name) == 0)
                    {
                        object sourceValue = piSource.GetValue(item, null);
                        string strSearch = searchValue.ToString();
                        string strSource = (sourceValue == null) ? string.Empty : sourceValue.ToString();
                        if (string.Compare(strSearch, strSource) != 0) //有一个属性不等,就说明不匹配
                        {
                            flag = false;
                            break;
                        }
                    }
                }

                if (!flag)
                {
                    break;
                }
            }
            if (flag)
            {
                listT.Add(item);
            }
        }

        /// <summary>
        ///  判断是否已经存在一条id相同的记录
        /// </summary>
        /// <param name="xmlPath"></param>
        /// <param name="rootName"></param>
        /// <param name="eleName"></param>
        /// <param name="IDName">主键名称</param>
        /// <param name="Id">主键值</param>
        /// <returns></returns>
        public static bool IsAlreadyExistsObj(string xmlPath, string rootName, string eleName, string IDName, string ID)
        {
            BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;//反射标示
            bool flag = false;
            List<T> listT = GetObject(xmlPath, rootName, eleName);
            foreach (T item in listT)
            {
                //通过反射绑定父级属性
                Type itemType = item.GetType();
                foreach (PropertyInfo itemProp in itemType.GetProperties(bf))
                {
                    //如果属性名和ID名称相同  比较是否已经存在一条相同id的记录
                    if (string.Compare(itemProp.Name.ToUpper(), IDName.ToUpper()) == 0)
                    {
                        object searchValue = itemProp.GetValue(item, null);
                        if (searchValue != null)
                        {

                            if (string.Compare(searchValue.ToString(), ID) == 0)
                            {
                                flag = true;
                                break;
                            }
                        }
                    }
                }
            }
            return flag;
        }

        #endregion

        #region 删除

        /// <summary>
        /// 删除节点
        /// </summary>
        /// <param name="xmlPath"></param>
        /// <param name="rootName"></param>
        /// <param name="eleName"></param>
        /// <param name="idName">主键名称</param>
        /// <param name="id">主键值</param>
        /// <returns></returns>
        public static bool DeleteOneT(string xmlPath, string rootName, string eleName, string idName, string id)
        {
            bool flag = false;
            if (string.IsNullOrEmpty(xmlPath))
            {
                throw new Exception("xml文件路径为空");
            }

            try
            {
                bool isExists = IsAlreadyExistsObj(xmlPath, rootName, eleName, idName, id);
                if (!isExists) //删除的那条记录已经不存在了
                {
                    flag = true;
                }
                else
                {
                    XDocument xmlDoc = XDocument.Load(xmlPath);
                    List<XElement> listElements = null;
                    var query =
                        from list in xmlDoc.Element(rootName).Elements(eleName)
                        select list;
                    listElements = query.ToList<XElement>();

                    if (listElements != null && listElements.Count > 0)
                    {
                        foreach (XElement item in listElements)
                        {
                            if (string.Compare((string)item.Attribute(idName), id) == 0)
                            {
                                item.Remove();
                                xmlDoc.Save(xmlPath);
                                flag = true;
                                break;
                            }
                        }
                    }
                }
            }
            catch
            {
                flag = false;
            }
            return flag;
        }

        #endregion

        #region 修改

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="xmlPath"></param>
        /// <param name="rootName"></param>
        /// <param name="eleName"></param>
        /// <param name="idName"></param>
        /// <param name="id"></param>
        /// <param name="objT"></param>
        /// <returns></returns>
        public static bool ModifyOneT(string xmlPath, string rootName, string eleName, string idName, string id, T objT)
        {
            bool flag = false;
            if (string.IsNullOrEmpty(xmlPath))
            {
                throw new Exception("xml文件路径为空");
            }
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(xmlPath);
                XmlNode root = xmlDoc.SelectSingleNode(rootName);
                XmlNodeList nodeList = root.ChildNodes;

                BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;//反射标示
                Type objTType = objT.GetType(); //通过反射绑定属性
                PropertyInfo[] propInfos = objTType.GetProperties(bf);

                if (nodeList != null && nodeList.Count > 0)
                {
                    foreach (XmlNode item in nodeList)
                    {
                        if (item is XmlElement)
                        {
                            XmlElement ele = (XmlElement)item;
                            if (string.Compare(ele.GetAttribute(idName), id) == 0)
                            {
                                //修改这条记录
                                foreach (PropertyInfo pi in propInfos)
                                {
                                    string attName = pi.Name;
                                    string attValue = string.Empty;
                                    object obj = pi.GetValue(objT, null);
                                    if (obj != null)
                                    {
                                        attValue = obj.ToString();
                                    }
                                    //设置该节点属性
                                    ele.SetAttribute(attName, attValue);
                                }
                                xmlDoc.Save(xmlPath);
                                flag = true;
                                break;
                            }
                        }
                    }
                }
            }
            catch
            {
                flag = false;
            }

            return flag;
        }

        #endregion

        #region 添加

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="xmlPath"></param>
        /// <param name="rootName"></param>
        /// <param name="eleName"></param>
        /// <param name="idName"></param>
        /// <param name="id"></param>
        /// <param name="objT"></param>
        /// <returns></returns>
        public static bool InsertOneT(string xmlPath, string rootName, string eleName, string idName, string id, T objT)
        {
            bool flag = false;
            if (string.IsNullOrEmpty(xmlPath))
            {
                throw new Exception("xml文件路径为空");
            }

            XmlDocument xmlDoc = new XmlDocument();
            try
            {
                Monitor.Enter(xmlDoc);
                if (IsAlreadyExistsObj(xmlPath, rootName, eleName, idName, id)) //如果xml文件中已经存在,不允许添加
                {
                    flag = false;
                }
                else
                {
                    xmlDoc.Load(xmlPath);
                    XmlNode root = xmlDoc.SelectSingleNode(rootName);

                    XmlElement xeFather = xmlDoc.CreateElement(eleName);//创建一个节点
                    BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;//反射标示
                    Type objTType = objT.GetType(); //通过反射绑定属性
                    PropertyInfo[] propInfos = objTType.GetProperties(bf);
                    foreach (PropertyInfo pi in propInfos)
                    {
                        string attName = pi.Name;
                        string attValue = string.Empty;
                        object obj = pi.GetValue(objT, null);
                        if (obj != null)
                        {
                            attValue = obj.ToString();
                        }
                        xeFather.SetAttribute(attName, attValue);//设置该节点属性
                    }
                    root.AppendChild(xeFather);
                    xmlDoc.Save(xmlPath);
                    flag = true;
                }
            }
            catch
            {
                flag = false;
            }
            finally
            {
                Monitor.Exit(xmlDoc);
            }

            return flag;
        }

        #endregion

    }
}
XmlHelper

在表现层调用如下:

Code

ps,分层结构可能不合理,但是简单的小数据量的增删改查没有问题,读者可以下载demo试试。
ps2,如果xml文件结构有多层的子节点,只要递归调用这个类里的方法就可以了。
ps3,在插入时,xml文件的特殊字符没有处理,可能导致xml文件不符合语法规范,希望你能够留意。
demo下载:Demo

posted on 2009-09-25 14:09  JeffWong  阅读(1423)  评论(2编辑  收藏  举报