我们常常需要读取xml文件,把里面的信息转化为我们自定义的类型,或则吧自定义类型转化为Xml字符串。在这里介绍一个比较简单的对象转化方法。在我自己的Framwork里面也多次用到。里面涉及到节点、属性、集合。
示例一 该xml文件涉及到属性、节点集合不涉及个节点:
<?xml version="1.0" encoding="utf-8"?>
<databaseSettings defaultInstance="CheckboxSql">
<databaseTypes>
<databaseType name="sqlserver" type="Framework.Data.Sql.SqlDatabase,Framework" />
</databaseTypes>
<instances>
<instance name="CheckboxSql" type="sqlserver" connectionString="DefaultConnectionString" />
<instance name="TestProvider" type="sqlserver" connectionString="TestConnectionString" />
<instance name="DBAuthenticationProvider" type="sqlserver" connectionString="FrameworkConnectionString" />
<instance name="DBProfileProvider" type="sqlserver" connectionString="TestConnectionString" />
</instances>
</databaseSettings>
自定相关类
[XmlRoot("databaseType", Namespace = "")]
public class DatabaseTypeData
{
// Fields
private string name;
private string typeName;
// Properties
[XmlAttribute("name")]
public string Name
{
get
{ return this.name; }
set
{ this.name = value; }
}
[XmlAttribute("type")]
public string TypeName
{
get
{ return this.typeName; }
set
{ this.typeName = value; }
}
}
[XmlRoot("instance", Namespace = "")]
public class InstanceData
{
// Fields
private string _connectionString;
private string _name;
private string _typeName;
// Properties
[XmlAttribute("connectionString")]
public string ConnectionString
{
get
{ return this._connectionString; }
set
{ this._connectionString = value; }
}
[XmlAttribute("type")]
public string DatabaseTypeName
{
get
{ return this._typeName; }
set
{
this._typeName = value;
}
}
[XmlAttribute("name")]
public string Name
{
get
{ return this._name; }
set
{ this._name = value; }
}
}
[XmlRoot("databaseSettings", Namespace = "")]
public class DatabaseSettings
{
// Fields
private List<DatabaseTypeData> _databaseTypes = new List<DatabaseTypeData>();
private List<InstanceData> _instances = new List<InstanceData>();
private string defaultInstance;
// Properties
[XmlArray(ElementName = "databaseTypes", Namespace = ""), XmlArrayItem(ElementName = "databaseType", Namespace = "", Type = typeof(DatabaseTypeData))]
public List<DatabaseTypeData> DatabaseTypes
{
get { return this._databaseTypes; }
set { this._databaseTypes = value; }
}
[XmlAttribute("defaultInstance")]
public string DefaultInstance
{
get
{ return this.defaultInstance; }
set
{ this.defaultInstance = value; }
}
[XmlArrayItem(ElementName = "instance", Namespace = "", Type = typeof(InstanceData)), XmlArray(ElementName = "instances", Namespace = "")]
public List<InstanceData> Instances
{
get
{ return this._instances; }
set { this._instances = value; }
}
public static implicit operator DatabaseSettings(string xml)
{
return xml.GetInstance<DatabaseSettings>();
}
}
示例二 xml文件设计到属性 复杂的节点原属
<book year="1994">
<title>TCP/IP Illustrated</title>
<author>
<last>Stevens</last>
<first>W.</first>
</author>
<publisher>Addison-Wesley</publisher>
<price>65.95</price>
</book>
自定相关类
[XmlRoot(ElementName = "author", Namespace = "")]
public class Author
{
string first;
[XmlElement(ElementName = "first")]
public string FirstName
{
set { first = value; }
get { return first; }
}
string last;
[XmlElement(ElementName = "last")]
public string LastName
{
set { last = value; }
get { return last; }
}
}
[XmlRoot(ElementName = "book", Namespace = "")]
public class Book
{
string title;
[XmlElement(ElementName = "title")]
public string Title
{
set { title = value; }
get { return title; }
}
Author author;
[XmlElement(ElementName = "author",Type=typeof(Author))]
public Author Author
{
set { author = value; }
get { return author; }
}
string publisher;
[XmlElement(ElementName = "publisher")]
public string Publisher
{
set { publisher = value; }
get { return publisher; }
}
double price;
[XmlElement(ElementName = "price", Type = typeof(double))]
public double Price
{
set { price = value; }
get { return price; }
}
int year;
[XmlAttribute("year")]
public int Year
{
set { year = value; }
get { return year; }
}
public static implicit operator Book(string xml)
{
return xml.GetInstance<Book>();
}
}
定义2个帮助类
/// <summary>
/// 通过反射访问属性(Attribute)信息的工具类
/// </summary>
public static class AttributeHelper
{
/// <summary>
/// 获取某个类型包括指定属性的集合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="type"></param>
/// <returns></returns>
public static IList<T> GetCustomAttributes<T>(Type type) where T : Attribute
{
if (type == null) throw new ArgumentNullException("type");
T[] attributes = (T[])(type.GetCustomAttributes(typeof(T), false));
return (attributes.Length == 0) ? null : new List<T>(attributes);
}
/// <summary>
/// 获得某各类型包括指定属性的所有方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="type"></param>
/// <returns></returns>
public static IList<MethodInfo> GetMethodsWithCustomAttribute<T>(Type type) where T : Attribute
{
if (type == null) throw new ArgumentNullException("type");
MethodInfo[] methods = type.GetMethods();
if ((methods == null) || (methods.Length == 0)) return null;
IList<MethodInfo> result = new List<MethodInfo>();
foreach (MethodInfo method in methods)
if (method.IsDefined(typeof(T), false))
result.Add(method);
return result.Count == 0 ? null : result;
}
/// <summary>
/// 获取某个方法指定类型属性的集合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="method"></param>
/// <returns></returns>
public static IList<T> GetMethodCustomAttributes<T>(MethodInfo method) where T : Attribute
{
if (method == null) throw new ArgumentNullException("method");
T[] attributes = (T[])(method.GetCustomAttributes(typeof(T), false));
return (attributes.Length == 0) ? null : new List<T>(attributes);
}
/// <summary>
/// 获取某个方法指定类型的属性
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="method"></param>
/// <returns></returns>
public static T GetMethodCustomAttribute<T>(MethodInfo method) where T : Attribute
{
IList<T> attributes = GetMethodCustomAttributes<T>(method);
return (attributes == null) ? null : attributes[0];
}
/// <summary>
/// 获得某各类型包括指定属性的所有属性
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="type"></param>
/// <returns></returns>
public static IList<PropertyInfo> GetPropertyWithCustomAttribute<T>(Type type) where T : Attribute
{
if (type == null) throw new ArgumentNullException("type");
PropertyInfo[] propes = type.GetProperties();
if ((propes == null) || (propes.Length == 0)) return null;
IList<PropertyInfo> result = new List<PropertyInfo>();
foreach (PropertyInfo p in propes)
if (p.IsDefined(typeof(T), false))
result.Add(p);
return result.Count == 0 ? null : result;
}
/// <summary>
/// 获取某个属性指定类型属性的集合
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="method"></param>
/// <returns></returns>
public static IList<T> GetPropertyCustomAttributes<T>(PropertyInfo property) where T : Attribute
{
if (property == null) throw new ArgumentNullException("method");
T[] attributes = (T[])(property.GetCustomAttributes(typeof(T), false));
return (attributes.Length == 0) ? null : new List<T>(attributes);
}
/// <summary>
/// 获取某个属性指定类型的属性
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="method"></param>
/// <returns></returns>
public static T GetPropertyCustomAttribute<T>(PropertyInfo property) where T : Attribute
{
IList<T> attributes = GetPropertyCustomAttributes<T>(property);
return (attributes == null) ? null : attributes[0];
}
}
public static class ExtendClass
{
static List<Type> types;
static ExtendClass()
{
types = new List<Type>();
types.Add(typeof(byte));
types.Add(typeof(short));
types.Add(typeof(int));
types.Add(typeof(long));
types.Add(typeof(sbyte));
types.Add(typeof(ushort));
types.Add(typeof(uint));
types.Add(typeof(ulong));
types.Add(typeof(float));
types.Add(typeof(double));
types.Add(typeof(decimal));
types.Add(typeof(char));
types.Add(typeof(string));
types.Add(typeof(Enum));
}
public static T GetInstance<T>(this string xml) where T : class
{
XmlTextReader xmlReader = new XmlTextReader(new StringReader(xml));
XmlSerializer serializer = new XmlSerializer(typeof(T), "");
return serializer.Deserialize(xmlReader) as T;
}
public static string ToXml<T>(this T t) where T : class
{
XElement element= ToXml(t, t.GetType());
if (element != null)
return element.ToString();
return string.Empty;
}
public static XElement ToXml(object obj, Type type)
{
IList<XmlRootAttribute> xmlRoots = AttributeHelper.GetCustomAttributes<XmlRootAttribute>(type);
if (xmlRoots == null || xmlRoots.Count < 1) return null;
XmlRootAttribute xmlRoot = xmlRoots[0];
string root = xmlRoot.ElementName;
XNamespace ns = xmlRoot.Namespace;
XDocument doc = new XDocument(new XElement(root));
IList<PropertyInfo> xmlAttributes = AttributeHelper.GetPropertyWithCustomAttribute<XmlAttributeAttribute>(type);
if (xmlAttributes != null && xmlAttributes.Count > 0)
{
foreach (PropertyInfo p in xmlAttributes)
{
XmlAttributeAttribute xmlattribute = AttributeHelper.GetPropertyCustomAttribute<XmlAttributeAttribute>(p);
string attributeName = xmlattribute.AttributeName;
object attributeValue = p.GetValue(obj, null);
doc.Root.Add(new XAttribute(attributeName, attributeValue));
}
}
IList<PropertyInfo> xmlElements = AttributeHelper.GetPropertyWithCustomAttribute<XmlElementAttribute>(type);
if (xmlElements != null && xmlElements.Count > 0)
{
foreach (PropertyInfo p in xmlElements)
{
XmlElementAttribute xmlelement = AttributeHelper.GetPropertyCustomAttribute<XmlElementAttribute>(p);
string elementName = xmlelement.ElementName;
object elementValue = p.GetValue(obj, null);;
Type t = xmlelement.Type;
if (t!=null && !types.Contains(t))
elementValue = ToXml(elementValue, t);
doc.Root.Add(new XElement(elementName,elementValue));
}
}
IList<PropertyInfo> xmlarrays = AttributeHelper.GetPropertyWithCustomAttribute<XmlArrayAttribute>(type);
if (xmlarrays != null && xmlarrays.Count > 0)
{
foreach (PropertyInfo p in xmlarrays)
{
XmlArrayAttribute xmlarray = AttributeHelper.GetPropertyCustomAttribute<XmlArrayAttribute>(p);
string array = xmlarray.ElementName;
XElement element = new XElement(array);
XmlArrayItemAttribute xmlArrayItem = AttributeHelper.GetPropertyCustomAttribute<XmlArrayItemAttribute>(p);
string itemName = xmlArrayItem.ElementName;
Type subtype = xmlArrayItem.Type;
object o = p.GetValue(obj, null);
IList c = (IList)o;
for (int i = 0; i < c.Count; i++)
{
XElement itemvalue = ToXml(c[i], subtype);
element.Add(new XElement(itemvalue));
}
doc.Root.Add(element);
}
}
return doc.Root;
}
}
使用方式:
XDocument doc = XDocument.Load(Server.MapPath("DatabaseConfiguration.xml"));
XElement element = doc.Root;
DatabaseSettings dbset = element.ToString();
string xml = dbset.ToXml();
XDocument docbook = XDocument.Load(Server.MapPath("books.xml"));
XElement elementbook = docbook.Root;
Book book = elementbook.ToString();
string xmlbook = book.ToXml();
看多简单 哈哈。
其中AttributeHelper也可以在http://blog.csdn.net/dz45693/archive/2009/11/15/4813397.aspx 查看