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