我的XML看起来像这样:
<root>
<base type="a">
<common>1</common>
<concreteA>one</concreteA>
</base>
<base type="b">
<common>2</common>
<concreteB>two</concreteB>
</base>
</root>
这样的课程:
public class Root
{
public List<Base> Bases { get; set; }
}
public class Base
{
public int Common { get; set; }
}
public class A : Base
{
public string ConcreteA { get; set; }
}
public class B : Base
{
public string ConcreteB { get; set; }
}
如何将其反序列化为对象?当每个基本节点使用XmlArrayItemAttribute( ElementName, Type )]
使用不同的名称时,我看到很多posts如何执行此操作,但我需要根据元素type
属性选择它。
答案 0 :(得分:0)
这是一种非常基本的方式,但我认为它有效。我认为如果类类型是一个元素而不是一个属性,那么你应该能够以声明方式解析它。
代码基本上打开了type属性top确定要创建的子类,然后手动填充具体属性和公共属性。
[System.Xml.Serialization.XmlType("base")]
public class Base
{
[System.Xml.Serialization.XmlElement("common")]
public int Common { get; set; }
}
public class A : Base
{
public string ConcreteA { get; set; }
}
public class B : Base
{
public string ConcreteB { get; set; }
}
[System.Xml.Serialization.XmlRootAttribute("root")]
public class Root : System.Xml.Serialization.IXmlSerializable
{
[System.Xml.Serialization.XmlElement("base")]
public List<Base> Bases { get; set; }
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
this.Bases = new List<Base>();
var document = XDocument.Load(reader);
foreach (var element in document.Root.Elements())
{
Base baseElement = null;
var attr = element.Attribute("type");
if(attr.Value == "a")
{
var a = new A();
a.ConcreteA = element.Element("concreteA").Value;
baseElement = a;
}
else
{
var b = new B();
b.ConcreteB = element.Element("concreteB").Value;
baseElement = b;
}
baseElement.Common = int.Parse(element.Element("common").Value);
this.Bases.Add(baseElement);
}
this.Bases.Dump();
}
public void WriteXml(XmlWriter writer)
{
throw new NotSupportedException();
}
}
void Main()
{
var xmlString = @"<root>
<base type=""a"">
<common>1</common>
<concreteA>one</concreteA>
</base>
<base type=""b"">
<common>2</common>
<concreteB>two</concreteB>
</base>
</root>";
var stream = new StringReader(xmlString);
var deserializer = new System.Xml.Serialization.XmlSerializer(typeof(Root));
var result = (Root)deserializer.Deserialize(stream);
}