C# 派生类C的XML反序列化#

C# 派生类C的XML反序列化#,c#,xml,deserialization,C#,Xml,Deserialization,我有下一个代码: [XmlRoot(ElementName = "Container")] public class Container { [XmlArray("Items", IsNullable = false)] [XmlArrayItem("Item")] public List<BaseItem> Items { get; set; } = new List<BaseItem>(); } public class BaseItem

我有下一个代码:

[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;}
}
[XmlRoot(ElementName=“Container”)]
公营货柜{
[XmlArray(“Items”,IsNullable=false)]
[XmlArrayItem(“项目”)]
公共列表项{get;set;}=new List();
}
公共类基项{
[xmldattribute(“SomeField”)]
公共字符串SomeField{get;set;}
}
公共类DerivedItem:BaseItem{
[XmlAttribute(“其他字段”)]
公共字符串OtherField{get;set;}
}
如何反序列化:

<Container>
   <Items>
        <Item SomeField="Value"/>
        <Item SomeField="Value" OtherField="OtherValue"/>
   </Items>
</Container>


所以,容器对象中的Items字段可以包含上述XML中的BaseItem和DerivedItem对象?

当然,不能这样做,因为反序列化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;}
}
//在此处定义其他方法和类
[XmlRoot(ElementName=“Container”)]
公营货柜{
[XmlArray(“Items”,IsNullable=false)]
[XmlArrayItem(“项目”)]
公共列表项{get;set;}
}
公共类派生项
{
[xmldattribute(“SomeField”)]
公共字符串SomeField{get;set;}
[XmlAttribute(“其他字段”)]
公共字符串OtherField{get;set;}
指定的公共bool otherfield{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();
}
void Main()
{
var xml=@”
";
var stream=newmemoryStream(Encoding.UTF8.GetBytes(xml));
var ser=新的XmlSerializer(typeof(Container));
var container=(容器)序列反序列化(流);
container.Dump();
}

我们可以从您没有发布有效的XML开始吗

元素是独一无二的。继承(派生类型)必须更改元素名称。这是XML标准,因为元素名称是XML模式确定存在哪些元素的方式


执行此操作后,您可以添加多个XmlArrayItem条目-第二个重载采用包含项的类型。

XmlSerializer
根据元素名称确定类型。用
替代是可以接受的吗?实际上这不是有效的XML,所以所有的答案都是废话。您必须按照XML标准按元素名分隔继承。然后用子类的名称和类型定义多个XmlArrayItem条目。这是XML—根据XML规范,您在这里询问的内容没有XML派生类。或者,您愿意使用
?您可以通过添加。另请参见.dbc,已经尝试过了。这就是我需要的。谢谢。好吧,如果他遵守XML标准,他可以,而他的样本数据却不遵守。根据XML规范,示例数据不包含任何派生元素。当他询问XML解决方案时-您的解决方案不起作用。他想反序列化给定的XML。。。我给了他一个有效的反序列化版本。不,他不是这么说的。你似乎觉得他无法控制。如果他有-那么这不是派生类解决方案。看,如果查看XML模式会发生什么?Ups,不使用派生类。我不是说他没有控制权。他的XML是有效的。他从不费心展示如何使用模式进行验证。我刚刚展示了一种更改代码的方法,以便使用我假设他正在使用的XmlSerializer读取他发布的xml?“显示最小代码以演示问题”。你可以从一个过于简单的示例中得出结论,或者指责他不够聪明,没有遵守网站规则。实际上,属性
xsi:type=“DerivedItem”
也可以用来指定类型。见和。在任何情况下,原始XML都是完全有效的,只是序列化程序不支持所需的模式映射。