C# XML与实体互转,实体类反序列化属性对应转换成 XmlAttribute

一、前言

可扩展标记语言 (XML) 是具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML是用来存储数据的,重在数据本身。本文中的代码是几个月前整理的,最近几个月的时间很少写随笔,除了工作以外,主要还是忙于整理自己的框架。这篇随笔主要是针对于XML的特性Attribute与实体之间的匹配与转换,其中的内容包括反射、XML以及LinqToXml,代码的内容也是想到什么就写什么,纯属练习下手感,仅供参考。下一篇随笔将以另外的形式来转换Xml为对象实体,当然,也是以反射为主,和本随笔中的思路差不多,主要是XML的格式和解决方案不同而已。对于如何将对象转换成Xml的话,主要还是看情况,仅仅转换简单的对象的话,直接反射就可以生成。对于复杂的对象的话,可以采用dynamic,树结构和递归算法的方案来定制XML。

XmlAttributeUtility的转换操作相对来说比较简单,采用反射+LinqToXml转换操作就很简单了,主要实现方法为public static XElement Convert(T entity) where T : new(),其他方法都是以该方法作为基础来进行操作。为什么用LinqToXml?主要原因是LinqToXml比Xml更方便,很多细节方面不需要考虑太多。代码如下:

实体类:

  public class Document
    {
        public Document()
        {
            this.OrderMethod = new Util.OrderMethod();
            this.SortMethod = new Util.SortMethod();
        }

        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public Document(string taskGuid, string dataGuid, string dataType, int pageSize, int pageIndex, int total, string requestTime, string returnTime, string sortMethod, string orderMethod)
        {
            this.TaskGuid = taskGuid;
            this.DataGuid = dataGuid;
            this.DataType = dataType;
            this.PageSize = pageSize;
            this.PageIndex = pageIndex;
            this.Total = total;
            this.RequestTime = requestTime;
            this.ReturnTime = returnTime;
            this.OrderMethod = new Util.OrderMethod() { Value = orderMethod };
            this.SortMethod = new Util.SortMethod() { Value = sortMethod };
        }
        /// 
        /// 组件标识
        /// 
        public string TaskGuid { get; set; }
        /// 
        /// 车辆轨迹回放
        /// 
        public string DataGuid { get; set; }
        /// 
        /// 数据类型
        /// 
        public string DataType { get; set; }
        /// 
        /// 每页记录数
        /// 
        public int PageSize { get; set; }
        /// 
        /// 检索的页号
        /// 
        public int PageIndex { get; set; }
        /// 
        /// 数据量
        /// 
        public int Total { get; set; }
        /// 
        /// 查询请求时间
        /// 
        public string RequestTime { get; set; }
        /// 
        /// 查询结果生成时间
        /// 
        public string ReturnTime { get; set; }
        /// 
        /// 排序字段名
        /// 
        public SortMethod SortMethod { get; set; }
        /// 
        /// 排序方式
        /// 
        public OrderMethod OrderMethod { get; set; }
        /// 
        /// 
        /// 
        public IEnumerable Data { get; set; }
    }



    public class SortMethod
    {
        /// 
        /// TEXT
        /// 
        public string Type { get { return "TEXT"; } }
        /// 
        /// 排序字段名
        /// 
        public string Value { get; set; }
    }

    public class OrderMethod
    {
        /// 
        /// TEXT
        /// 
        public string Type { get { return "TEXT"; } }
        /// 
        /// 排序方式[asc|desc]
        /// 
        public string Value { get; set; }
    }

转换工具类:
namespace XmlConvert.Framework
{
    /// 
    /// Entity to XML Convert
    /// 
    public class XmlAttributeUtility
    {
        public static bool Append(string inputUri, string parentXPath,
            List entities) where T : new()
        {
            return RepalceOrAppend(inputUri, parentXPath, entities, true);
        }

        public static bool Replace(string inputUri, string parentXPath,
            List entities) where T : new()
        {
            return RepalceOrAppend(inputUri, parentXPath, entities, false);
        }

        public static bool RepalceOrAppend(string inputUri, string parentXPath,
            List entities, bool appendToLast) where T : new()
        {
            if (!File.Exists(inputUri) || string.IsNullOrWhiteSpace(parentXPath)
                || entities == null || entities.Count == 0)
            {
                return false;
            }

            XmlDocument document = new XmlDocument();
            document.Load(inputUri);
            XmlElement parentElement = document.DocumentElement.SelectSingleNode(parentXPath) as XmlElement;

            if (parentElement == null)
            {
                return false;
            }

            string elementContent = ConvertToString(entities);

            if (appendToLast)
            {
                parentElement.InnerXml += elementContent;
            }
            else
            {
                parentElement.InnerXml = elementContent;
            }

            document.Save(inputUri);
            document = null;

            return true;
        }
        /// 
        /// 实体集合转换成XML字符串
        /// 
        /// 
        /// 
        /// 
        public static string ConvertToString(List entities) where T : new()
        {
            List elements = Convert(entities);
            if (elements == null || elements.Count == 0)
            {
                return string.Empty;
            }

            StringBuilder builder = new StringBuilder();
            elements.ForEach(p => builder.AppendLine(p.ToString()));

            return builder.ToString();
        }
        /// 
        /// 实体集合转换成XElement集合
        /// 
        /// 
        /// 
        /// 
        public static List Convert(List entities) where T : new()
        {
            if (entities == null || entities.Count == 0)
            {
                return new List();
            }

            List elements = new List();
            XElement element;

            foreach (var entity in entities)
            {
                element = Convert(entity);
                if (element == null)
                {
                    continue;
                }

                elements.Add(element);
            }

            return elements;
        }

        /// 
        /// 实体转换成XML字符串
        /// 
        /// 
        /// 
        /// 
        public static string ConvertToString(T entity) where T : new()
        {
            XElement element = Convert(entity);
            return element == null ? string.Empty : element.ToString();
        }
        /// 
        /// 实体转换成XElement
        /// 
        /// 
        /// 
        /// 
        public static XElement Convert(T entity) where T : new()
        {
            if (entity == null)
            {
                return null;
            }
            string className = GetClassName();
            XElement element = new XElement(className);
            Convert(element, entity);
            return element;
        }


        private static void Convert(XElement element, T entity) where T : new()
        {
            List properties = entity.GetType().GetProperties().ToList();
            string propertyName = string.Empty;
            object propertyValue = null;
            foreach (PropertyInfo property in properties)
            {
                if (property.CanRead)
                {
                    propertyName = GetPropertyName(property);
                    propertyValue = property.GetValue(entity, null);
                    //
                    if (property.PropertyType.Namespace == "System")
                    {
                        //属性名为Value ,把值写到元素内容中
                        if (propertyName.Equals("Value", StringComparison.CurrentCultureIgnoreCase))
                            element.Value = propertyValue.ToString();
                        else
                            element.SetAttributeValue(propertyName, propertyValue);
                    }
                    else
                    {
                        XElement child = new XElement(propertyName);
                        //命名空间非System,属性可能是自定义封装类
                        Convert(child, propertyValue);
                        element.Add(child);
                    }
                }
            }

        }



        public static XElement ConvertBk(T entity) where T : new()
        {
            if (entity == null)
            {
                return null;
            }

            string className = GetClassName();
            XElement element = new XElement(className);

            List properties = typeof(T).GetProperties().ToList();
            string propertyName = string.Empty;
            object propertyValue = null;



            foreach (PropertyInfo property in properties)
            {
                if (property.CanRead)
                {
                    propertyName = GetPropertyName(property);
                    propertyValue = property.GetValue(entity, null);
                    if (property.PropertyType.Namespace == "System")
                    {
                        element.SetAttributeValue(propertyName, propertyValue);
                    }
                    else
                    {
                        XElement xmlChild = new XElement(propertyName);
                        Type type = property.PropertyType;
                        var childList = type.GetProperties().ToList();

                        foreach (PropertyInfo child in childList)
                        {
                            if (child.CanRead)
                            {
                                propertyValue = child.GetValue(propertyValue, null);
                                xmlChild.SetAttributeValue(GetPropertyName(child), propertyValue);
                                element.Add(xmlChild);
                            }
                        }
                    }
                }
            }
            return element;
        }

        public static IList ParseByDescendants(string inputUri) where T : new()
        {
            if (!File.Exists(inputUri))
            {
                return new List();
            }

            XDocument document = XDocument.Load(inputUri);

            return ParseByDescendants(document);
        }

        public static IList ParseByDescendants(XDocument document) where T : new()
        {
            if (document == null)
            {
                return new List();
            }

            string xName = GetClassName();
            IEnumerable elements = document.Descendants(xName);

            return ParseByDescendants(elements);
        }

        public static IList ParseByDescendants(IEnumerable elements) where T : new()
        {
            if (elements == null || elements.Count() == 0)
            {
                return new List();
            }

            List entities = new List();

            foreach (XElement element in elements)
            {
                entities.Add(AddEntity(element.Attributes()));
            }

            return entities;
        }

        public static T AddEntity(IEnumerable attributes) where T : new()
        {
            if (attributes == null || attributes.Count() == 0)
            {
                return default(T);
            }

            T entity = new T();
            List properties = typeof(T).GetProperties().ToList();

            foreach (XAttribute attribute in attributes)
            {
                SetPropertyValue(properties, entity, attribute.Name.ToString(), attribute.Value);
            }

            return entity;
        }

        public static IList Parse(string inputUri, string parentXPath) where T : new()
        {
            if (!File.Exists(inputUri) || string.IsNullOrWhiteSpace(parentXPath))
            {
                return new List();
            }

            XmlDocument document = new XmlDocument();
            document.Load(inputUri);

            return Parse(document, parentXPath);
        }

        public static IList Parse(XmlDocument document, string parentXPath) where T : new()
        {
            if (document == null || string.IsNullOrWhiteSpace(parentXPath))
            {
                return new List();
            }

            XmlNode parentNode = document.DocumentElement.SelectSingleNode(parentXPath);

            if (parentNode == null)
            {
                return new List();
            }

            return Parse(parentNode);
        }

        public static IList Parse(XmlNode parentNode) where T : new()
        {
            if (parentNode == null || !parentNode.HasChildNodes)
            {
                return new List();
            }

            XmlNodeList nodeList = parentNode.ChildNodes;

            return Parse(nodeList);
        }

        public static IList Parse(XmlNodeList nodeList) where T : new()
        {
            if (nodeList == null || nodeList.Count == 0)
            {
                return new List();
            }

            List entities = new List();
            AddEntities(nodeList, entities);

            return entities;
        }

        public static IList Parse(string inputUri) where T : new()
        {
            if (!File.Exists(inputUri))
            {
                return new List();
            }

            XmlReaderSettings settings = new XmlReaderSettings();
            settings.IgnoreComments = true;
            settings.IgnoreWhitespace = true;

            XmlReader reader = XmlReader.Create(inputUri, settings);

            return Parse(reader);
        }

        public static IList Parse(XmlReader reader) where T : new()
        {
            if (reader == null)
            {
                return new List();
            }

            reader.ReadStartElement();
            string className = GetClassName();
            List properties = typeof(T).GetProperties().ToList();
            List entities = new List();
            T entity = new T();

            while (!reader.EOF)
            {
                if (!string.Equals(reader.Name, className) || !reader.IsStartElement())
                {
                    reader.Read();
                    continue;
                }

                entity = new T();

                if (!reader.HasAttributes)
                {
                    entities.Add(entity);
                    reader.Read();
                    continue;
                }

                SetPropertyValue(reader, properties, entity);
                entities.Add(entity);
                reader.Read();
            }

            reader.Close();

            return entities;
        }

        public static string GetClassName() where T : new()
        {
            string className = typeof(T).Name;

            ClassAttribute[] attributes = typeof(T).GetCustomAttributes(
                typeof(ClassAttribute), false) as ClassAttribute[];

            if (attributes != null && attributes.Length > 0)
            {
                if (!string.IsNullOrWhiteSpace(attributes[0].Name))
                {
                    className = attributes[0].Name;
                }
            }

            return className;
        }

        public static string GetPropertyName(PropertyInfo property)
        {
            if (property == null)
            {
                return string.Empty;
            }

            string propertyName = property.Name;

            PropertyAttribute[] attributes = property.GetCustomAttributes(typeof(PropertyAttribute),
                false) as PropertyAttribute[];

            if (attributes != null && attributes.Length > 0)
            {
                if (!string.IsNullOrWhiteSpace(attributes[0].Name))
                {
                    propertyName = attributes[0].Name;
                }
            }

            return propertyName;
        }

        private static void AddEntities(XmlNodeList nodeList,
            List entities) where T : new()
        {
            string className = GetClassName();
            List properties = typeof(T).GetProperties().ToList();
            T entity = new T();

            foreach (XmlNode xmlNode in nodeList)
            {
                XmlElement element = xmlNode as XmlElement;
                if (element == null || !string.Equals(className, element.Name))
                {
                    continue;
                }

                entity = new T();
                if (!element.HasAttributes)
                {
                    entities.Add(entity);
                    continue;
                }

                XmlAttributeCollection attributes = element.Attributes;
                foreach (XmlAttribute attribute in attributes)
                {
                    SetPropertyValue(properties, entity, attribute.Name, attribute.Value);
                }

                entities.Add(entity);
            }
        }

        private static void SetPropertyValue(XmlReader reader,
            List properties, T entity) where T : new()
        {
            while (reader.MoveToNextAttribute())
            {
                SetPropertyValue(properties, entity, reader.Name, reader.Value);
            }
        }

        private static void SetPropertyValue(List properties,
            T entity, string name, string value) where T : new()
        {
            foreach (var property in properties)
            {
                if (!property.CanWrite)
                {
                    continue;
                }

                string propertyName = GetPropertyName(property);

                if (string.Equals(name, propertyName))
                {
                    FuncDictionary action = new FuncDictionary();
                    object invokeResult = action.DynamicInvoke(property.PropertyType, value);

                    property.SetValue(entity, invokeResult, null);
                }
            }
        }

    }
}

结果:


  Create
  asc
  
    id
    int
    10
    
    
    
    
    id
  


转载:http://www.bianceng.cn/Programming/csharp/201311/38104_3.htm

你可能感兴趣的:(C# XML与实体互转,实体类反序列化属性对应转换成 XmlAttribute)