2013年12月13日 星期五

[C#]取得類別(Class)所有的成員(Members),以產生XML為例

前言

工作上寫到很多的XML Element,但看到有些人再寫複雜XML文件時,程式碼還冗長的,譬如以下的XML文件:

image

有些人可能不會想太多,很直覺的寫以下程式:

image

XmlDocument doc = new XmlDocument();
XmlElement company = doc.CreateElement("Company");
doc.AppendChild(company);

XmlElement id = doc.CreateElement("id");
id.InnerText = _Staff.id.ToString();
company.AppendChild(id);

XmlElement StaffName = doc.CreateElement("StaffName");
StaffName.InnerText = _Staff.StaffName.ToString();
company.AppendChild(StaffName);

XmlElement Birthday = doc.CreateElement("Birthday");
Birthday.InnerText = _Staff.Birthday.ToShortDateString();
company.AppendChild(Birthday);

XmlElement weight = doc.CreateElement("Dept");
weight.InnerText = _Staff.weight.ToString();
company.AppendChild(weight);

但根據DRY原則(Don’t repeat youself),如果發現一直在ctrl+v程式碼,一定要跟李組長一樣眉頭一皺,發現專案並不單純…


實做


因目前資料來源習慣都使用Entity Framework (強型別)來操作物件,取代ADO.NET的DataReader or DataTable (弱型別)


而C#能用PropertyInfo來抓取object的所有成員


故我將產生冗長的XmlElement抽出來處理:


private void CreateModelXmlElement(ref XmlDocument doc,ref XmlElement root)
{
Type type = model.GetType();
foreach (PropertyInfo propertyInfo in type.GetProperties())
{
if (propertyInfo.CanRead)
{
XmlElement _element = doc.CreateElement(propertyInfo.Name);
if (propertyInfo.PropertyType == typeof(DateTime))
{
//針對DateTime去做日期格式處理
DateTime value = Convert.ToDateTime(propertyInfo.GetValue(model, null));
_element.InnerText = value.ToShortDateString();
}
else
{
var value = propertyInfo.GetValue(model, null);
_element.InnerText = value.ToString();
}
root.AppendChild(_element);
}
}
}

這樣子就將麻煩的Create XmlElement縮短成以下片段:

XmlDocument doc = new XmlDocument();
XmlElement company = doc.CreateElement("Company");
doc.AppendChild(company);

CreateModelXmlElement(ref doc, ref company);

延伸閱讀


http://msdn.microsoft.com/zh-tw/library/system.reflection.propertyinfo(v=vs.110).aspx


http://stackoverflow.com/questions/3723934/using-propertyinfo-to-find-out-the-property-type


http://stackoverflow.com/questions/957783/loop-through-an-objects-properties-in-c-sharp

2 則留言:

  1. 也可以考慮直接用 XmlSerializer 來處理囉。如果這個xml的schema是挺固定的。

    回覆刪除
  2. XmlSerializer 我到沒有實做過,又學到一招了,待我實做後會在此篇文章補上,謝謝^_^

    回覆刪除