我有下一个代码:
[XmlRoot(ElementName = "Container")]
public class Container {
[XmlArray("Items", IsNullable = false)]
[XmlArrayItem("Item")]
public List<BaseItem> Items { get; set; } = new List<BaseItem>();
}
public class BaseItem {
[XmlAttribute("SomeField")]
public string SomeField {get;set;}
}
public class DerivedItem : BaseItem {
[XmlAttribute("OtherField")]
public string OtherField {get;set;}
}
如何反序列化:
<Container>
<Items>
<Item SomeField="Value"/>
<Item SomeField="Value" OtherField="OtherValue"/>
</Items>
</Container>
那么,Container对象中的Items字段可以包含上面XML的BaseItem和DerivedItem对象吗?
答案 0 :(得分:0)
嗯,你不能,因为反序列化XmlSerializer时不确定何时使用BaseItem或DerivedItem。所以你不应该在这里使用继承。
现在您可能需要知道是否指定了OtherField。
幸运的是,这是XmlSerializer可以做的事情。为此,您需要向表示项目的类添加一个bool属性OtherFieldSpecified,它指示OtherField是否正确...指定。
你应该使用
// Define other methods and classes here
[XmlRoot(ElementName = "Container")]
public class Container {
[XmlArray("Items", IsNullable = false)]
[XmlArrayItem("Item")]
public List<DerivedItem> Items { get; set; }
}
public class DerivedItem
{
[XmlAttribute("SomeField")]
public string SomeField {get;set;}
[XmlAttribute("OtherField")]
public string OtherField {get;set;}
public bool OtherFieldSpecified {get;set;}
}
所以稍微调整工作linqPad scribble给了我这段代码:
void Main()
{
var xml = @"
<Container>
<Items>
<Item SomeField=""Value""/>
<Item SomeField=""Value"" OtherField=""OtherValue""/>
</Items>
</Container>
";
var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml));
var ser = new XmlSerializer(typeof(Container));
var container = (Container) ser.Deserialize(stream);
container.Dump();
}
答案 1 :(得分:0)
我们可以从你开始不发布有效的XML吗?
元素是独一无二的。继承(派生类型)必须更改元素名称。这是XML标准,因为元素名称是XML Schema如何确定存在哪些元素。
你可以这样做,然后你可以添加多个XmlArrayItem条目 - 第二个重载采用所包含项的类型。