【发布时间】:2016-06-30 10:08:03
【问题描述】:
最初的问题
我想 serialize 和 List<IXmlSerializable> 动态更改 IXmlSerializable 类的 XmlType(所以我不能使用属性标签来做到这一点)
我尝试使用 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>Class(与不带属性标签的@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 };
}
}
使用代理的测试类:
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 来结束这一切,您的回答非常有帮助且内容丰富,我学到了很多东西。我不能投票给你,但我希望社区会这样做!
【问题讨论】:
标签: c# .net xml-serialization xmlserializer ixmlserializable