XML 是結構化標記語言,常用於資料儲存與交換。本文探討以反射、LINQ to XML 實作「XML Attribute 與實體屬性」的雙向映射,支援類別與屬性的自訂別名對應。程式碼為早期整理練習,供參考學習。
靜態建構函式建立 Dictionary<Type, Delegate>,DynamicInvoke 依型別執行對應委托:
public class FuncDictionary
{
public static IDictionary<Type, Delegate> Dictionary { get; private set; }
static FuncDictionary() { Dictionary = CreateDictionary(); }
public object DynamicInvoke(Type type, string arg)
{
if (type == null || Dictionary == null || !Dictionary.ContainsKey(type)) return null;
return Dictionary[type].DynamicInvoke(new object[] { arg });
}
static IDictionary<Type, Delegate> CreateDictionary()
{
var dict = new Dictionary<Type, Delegate>();
dict.Add(typeof(string), new Func<string, string>(p => p));
dict.Add(typeof(int), new Func<string, int>(p => p.AsInt()));
dict.Add(typeof(DateTime), new Func<string, DateTime>(p => p.AsDateTime()));
// ... 其他基礎型別 (decimal, float, bool, Color 等)
return dict;
}
}
提供兩種策略:
Parse<T>(XmlReader),效能佳,適合大檔案。Parse<T>(XmlNodeList),操作直觀。核心邏輯:取得目標類別名稱與可寫屬性清單,逐節點比對屬性名稱 (含別名),透過 FuncDictionary 轉型後寫入實體。
採用 LINQ to XML 簡化建構:
public static XElement Convert<T>(T entity) where T : new()
{
if (entity == null) return null;
string className = GetClassName<T>();
XElement element = new XElement(className);
foreach (PropertyInfo prop in typeof(T).GetProperties())
{
if (!prop.CanRead) continue;
string propName = GetPropertyName(prop);
object val = prop.GetValue(entity, null);
if (prop.PropertyType.Name == "Color") val = ColorTranslator.ToHtml((Color)val);
element.SetAttributeValue(propName, val);
}
return element;
}
並提供 ConvertToString、ToXDocument、ToXmlDocument 等多種輸出格式。
FuncDictionary:涵蓋正常、空值、異常輸入測試 (如 DateTime 解析)。XmlAttributeUtility:驗證各型別雙向轉換正確性。此方案適用於「元素屬性對應實體屬性」的扁平 XML 結構。下一篇將介紹「巢狀元素對應實體屬性」的另一種匹配模式。
原始碼下載:XmlAttribute 轉換與匹配原始碼