Config-POCO の読み取りに XML シリアライゼーションを使用します。
Visual Studio で XML ファイルの Intellisense サポートを取得するには、スキーマ ファイルが必要です。xsd.exe mylibrary.dll を使用してスキーマを作成できますが、これは正常に機能します。
しかし、オブジェクトをファイル システムにシリアル化する場合は、スキーマが常に作成されるようにしたいと考えています。xsd.exe を使用しない方法はありますか?
Config-POCO の読み取りに XML シリアライゼーションを使用します。
Visual Studio で XML ファイルの Intellisense サポートを取得するには、スキーマ ファイルが必要です。xsd.exe mylibrary.dll を使用してスキーマを作成できますが、これは正常に機能します。
しかし、オブジェクトをファイル システムにシリアル化する場合は、スキーマが常に作成されるようにしたいと考えています。xsd.exe を使用しない方法はありますか?
ありがとう、これは私にとって正しい方法でした。解決:
XmlReflectionImporter importer = new XmlReflectionImporter();
XmlSchemas schemas = new XmlSchemas();
XmlSchemaExporter exporter = new XmlSchemaExporter(schemas);
Type type = toSerialize.GetType();
XmlTypeMapping map = importer.ImportTypeMapping(type);
exporter.ExportTypeMapping(map);
TextWriter tw = new StreamWriter(fileName + ".xsd");
schemas[0].Write(tw);
tw.Close();
上記の Will によって投稿されたソリューションは、生成されたスキーマがさまざまなクラス メンバーの属性を反映していないことに気付いたことを除いて、素晴らしく機能しました。たとえば、シリアライゼーション ヒント属性 (以下のサンプルを参照) で装飾されたクラスは、正しくレンダリングされませんでした。
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; }
}
これに対処するために、リフレクションを使用してクラス階層を走査し、属性を読み取り、XmlReflectionImporter に渡すことができる XmlAttributeOverrides オブジェクトを設定するヘルパー関数をいくつか作成しました。
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();
}
}
これが他の誰かに役立つことを願っています。
System.Xml.Serialization.XmlSchemaExporter
クラスを見てください。正確な詳細を思い出すことはできませんが、その名前空間には、必要なことを行うのに十分な機能があります。