Các giải pháp được đăng trên đây bởi Will làm việc tuyệt vời, ngoại trừ tôi nhận ra rằng giản đồ được tạo ra không phản ánh các thuộc tính về các thành viên lớp khác nhau. Ví dụ: một lớp được trang trí với các thuộc tính gợi ý tuần tự hóa (xem mẫu bên dưới), sẽ không hiển thị chính xác.
public class Test
{
[XmlAttribute()]
public string Attribute { get; set; }
public string Description { get; set; }
[XmlArray(ElementName = "Customers")]
[XmlArrayItem(ElementName = "Customer")]
public List<CustomerClass> blah { get; set; }
}
Để giải quyết điều này, tôi đã tạo ra một vài chức năng helper mà dùng phản ánh để đi qua hệ thống phân cấp lớp, đọc các thuộc tính, và cư một đối tượng XmlAttributeOverrides có thể được chuyển vào XmlReflectionImporter.
public static void AttachXmlAttributes(XmlAttributeOverrides xao, Type t)
{
List<Type> types = new List<Type>();
AttachXmlAttributes(xao, types, t);
}
public static void AttachXmlAttributes(XmlAttributeOverrides xao, List<Type> all, Type t)
{
if(all.Contains(t))
return;
else
all.Add(t);
XmlAttributes list1 = GetAttributeList(t.GetCustomAttributes(false));
xao.Add(t, list1);
foreach (var prop in t.GetProperties())
{
XmlAttributes list2 = GetAttributeList(prop.GetCustomAttributes(false));
xao.Add(t, prop.Name, list2);
AttachXmlAttributes(xao, all, prop.PropertyType);
}
}
private static XmlAttributes GetAttributeList(object[] attributes)
{
XmlAttributes list = new XmlAttributes();
foreach (var attribute in attributes)
{
Type type = attribute.GetType();
if (type.Name == "XmlAttributeAttribute") list.XmlAttribute = (XmlAttributeAttribute)attribute;
else if (type.Name == "XmlArrayAttribute") list.XmlArray = (XmlArrayAttribute)attribute;
else if (type.Name == "XmlArrayItemAttribute") list.XmlArrayItems.Add((XmlArrayItemAttribute)attribute);
}
return list;
}
public static string GetSchema<T>()
{
XmlAttributeOverrides xao = new XmlAttributeOverrides();
AttachXmlAttributes(xao, typeof(T));
XmlReflectionImporter importer = new XmlReflectionImporter(xao);
XmlSchemas schemas = new XmlSchemas();
XmlSchemaExporter exporter = new XmlSchemaExporter(schemas);
XmlTypeMapping map = importer.ImportTypeMapping(typeof(T));
exporter.ExportTypeMapping(map);
using (MemoryStream ms = new MemoryStream())
{
schemas[0].Write(ms);
ms.Position = 0;
return new StreamReader(ms).ReadToEnd();
}
}
Hy vọng điều này sẽ giúp người khác.
Nguồn
2009-10-23 17:58:53
Bây giờ tôi thấy mã của bạn, 'trông' những gì tôi đã quay lại (chỉ không thể nhớ lại ở đâu!) – leppie