最初の質問
クラスのXmlTypeを動的serialize
にList<IXmlSerializable>
変更したい(属性タグを使用してそれを行うことはできません)IXmlSerializable
XmlAttributeOverridesを使用してそれを実行しようとしましたが、これまでのところ成功していません。
この問題を示すサンプル コードを次に示します。
IXmlSerializable クラス ( MSDNから) :
public class Person : IXmlSerializable
{
// Private state
private string personName;
// Constructors
public Person(string name)
{
personName = name;
}
public Person()
{
personName = null;
}
// Xml Serialization Infrastructure
public void WriteXml(XmlWriter writer)
{
writer.WriteString(personName);
}
public void ReadXml(XmlReader reader)
{
personName = reader.ReadString();
}
public XmlSchema GetSchema()
{
return (null);
}
// Print
public override string ToString()
{
return (personName);
}
}
テストクラス (出力にコンソールを使用):
class Program
{
static void Main(string[] args)
{
List<Person> lPersonList = new List<Person> {
new Person("First"),
new Person("Second"),
new Person("Third")
};
XmlAttributeOverrides lOverrides = new XmlAttributeOverrides();
XmlAttributes lAttributes = new XmlAttributes { XmlType = new XmlTypeAttribute("Employee") };
lOverrides.Add(typeof(Person), lAttributes);
XmlSerializer lSerialiser = new XmlSerializer(typeof(List<Person>), lOverrides, null, new XmlRootAttribute("Employees"), null);
XmlSerializerNamespaces lNamespaces = new XmlSerializerNamespaces();
lNamespaces.Add("", "");
lSerialiser.Serialize(Console.Out, lPersonList, lNamespaces);
System.Console.WriteLine("Enter any key to close.");
System.Console.ReadKey();
}
}
これが私が取得したいものです:
<Employees>
<Employee>First</Employee>
<Employee>Second</Employee>
<Employee>Third</Employee>
</Employees>
しかし、実行時にこのエラーが発生します:
System.InvalidOperationException: タイプ Person には XmlRoot 属性のみを指定できます。XmlSchemaProviderAttribute を使用してスキーマ タイプを指定してください。
私のPerson クラスが を実装していない場合IXmlSerializable
、すべてがうまく機能します...
誰かが私を助けてくれますか?
選択したソリューション ( @dbc answerに基づく)
@dbcが指摘したように、「サロゲート」クラスを使用することは、私が望むことを行う最も簡単な方法です。しかし、既に述べたように、Person 型を動的に変更する必要があるため、属性タグを使用できません。
だから私はまだXmlAttributeOverrides
私の最終的なデザインで使用しています、ここにあります:
サロゲートList<Person>
クラス(属性タグなしの @dbc と同じ) :
public class EmployeesListSurrogate
{
public List<Person> EmployeeList { get; set; }
public static implicit operator List<Person>(EmployeesListSurrogate surrogate)
{
return surrogate == null ? null : surrogate.EmployeeList;
}
public static implicit operator EmployeesListSurrogate(List<Person> employees)
{
return new EmployeesListSurrogate { EmployeeList = employees };
}
}
surrogate を使用してクラスをテストします。
class Program
{
static void Main(string[] args)
{
List<Person> lPersonList = new List<Person> {
new Person("First"),
new Person("Second"),
new Person("Third")
};
XmlAttributeOverrides lOverrides = new XmlAttributeOverrides();
XmlAttributes lEmployeesListAttributes = new XmlAttributes { XmlRoot = new XmlRootAttribute("Employees") };
lOverrides.Add(typeof(EmployeesListSurrogate), lEmployeesListAttributes);
XmlAttributes lEmployeeAttributes = new XmlAttributes { XmlElements = { new XmlElementAttribute("Employee") } };
lOverrides.Add(typeof(EmployeesListSurrogate), "EmployeeList", lEmployeeAttributes);
XmlSerializer lSerializer = new XmlSerializer(typeof(EmployeesListSurrogate), lOverrides);
XmlSerializerNamespaces lNamespaces = new XmlSerializerNamespaces();
lNamespaces.Add("", "");
lSerializer.Serialize(Console.Out, (EmployeesListSurrogate)lPersonList, lNamespaces);
}
}
@dbc に大いに感謝してこれを締めくくりたいと思います。あなたの答えは非常に役に立ち、有益でした。多くのことを学びました。私はあなたに賛成票を投じることはできませんが、コミュニティがそうしてくれることを願っています!