反序列化XML时如何修复值为null

时间:2019-03-31 20:37:00

标签: c# xml serialization

我有一个XML,想要根据自己的类反序列化。它会正确地反序列化,但是某些值将变为空。它不会给出错误,而且我不确定错误在哪里。

我尝试过更改类,序列化内存模型,然后检查输出,但是我都不喜欢。它需要遵循所提供的XML。

我的模特:

[XmlRoot(ElementName = "model", Namespace = "http://www.archimatetool.com/archimate")]
public class Model
{
    [XmlElement(ElementName = "folder")]
    public List<Folder> Folders { get; set; }
    [XmlElement(ElementName = "purpose")]
    public string Purpose { get; set; }
    [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
    public string Xsi { get; set; }
    [XmlAttribute(AttributeName = "archimate", Namespace = "http://www.w3.org/2000/xmlns/")]
    public string Archimate { get; set; }
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }
    [XmlAttribute(AttributeName = "id")]
    public string Id { get; set; }
    [XmlAttribute(AttributeName = "version")]
    public string Version { get; set; }
}

我的XML

<?xml version="1.0" encoding="UTF-8"?>
<archimate:model xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:archimate="http://www.archimatetool.com/archimate" name="Archisurance" id="11f5304f" version="3.1.1"> 
   <folder name="Business" id="8c90fdfa" type="business">
     <folder name="Actors" id="fa63373b">
       <element xsi:type="archimate:BusinessInterface" id="1544" name="mail"/>
     </folder>
   </folder>
   <purpose>An example of a fictional Insurance company.</purpose>
</archimate:model>

反序列化后得到的结果。 我不能发布图片(由于声誉),所以我只是发布一个链接。

result

我希望目的字段说“一个虚构的保险公司的例子”,但是它为空。

1 个答案:

答案 0 :(得分:0)

您可以使用以下数据模型反序列化XML:

[XmlRoot(ElementName = "model", Namespace = "http://www.archimatetool.com/archimate")]
[XmlType(Namespace = "http://www.archimatetool.com/archimate")]
public class Model
{
    [XmlElement(ElementName = "folder", Form = XmlSchemaForm.Unqualified)]
    public List<Folder> Folders { get; set; }

    [XmlElement(ElementName = "purpose", Form = XmlSchemaForm.Unqualified)]
    public string Purpose { get; set; }

    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName = "id")]
    public string Id { get; set; }

    [XmlAttribute(AttributeName = "version")]
    public string Version { get; set; }
}

[XmlType(Namespace = "http://www.archimatetool.com/archimate")]
public class Folder
{
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName = "id")]
    public string Id { get; set; }

    [XmlAttribute(AttributeName = "type")]
    public string Type { get; set; }

    [XmlElement(ElementName = "folder", Form = XmlSchemaForm.Unqualified)]
    public List<Folder> Folders { get; set; }

    [XmlElement(ElementName = "element", Form = XmlSchemaForm.Unqualified)]
    public List<Element> Element { get; set; }
}

[XmlType(Namespace = "http://www.archimatetool.com/archimate")]
[XmlInclude(typeof(BusinessInterface))]
public abstract class Element
{
    [XmlAttribute(AttributeName = "name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName = "id")]
    public string Id { get; set; }
}

[XmlType(TypeName = "BusinessInterface", Namespace = "http://www.archimatetool.com/archimate")]
public class BusinessInterface : Element
{
}

注意:

  • 根元素<archimate:model>archimate:命名空间中,但是其子元素不在任何命名空间中,因为archimate:命名空间不是默认命名空间。因此,有必要向XmlSerializer指出这些子元素与其父元素位于不同的命名空间中。设置XmlElementAttribute.Form = XmlSchemaForm.Unqualified即可完成。

    (不必指定属性在默认名称空间中,因为除非另外指定,否则所有XML属性均假定为不合格。)

  • xsi:type="archimate:BusinessInterface"属性的存在指示<element>属性是多态类型层次结构的一部分。 xsi:type属性是standard w3c attribute,它允许元素显式声明其类型。 XmlSerializer supports this attribute,实际上需要存在与xsi:type对应并通过[XmlInclude]属性声明的子类型。

    有关详细信息,请参见 How to: Control Serialization of Derived Classes

    在这里,我可以任意选择要包含在基类Element和派生类BusinessInterface中的属性。给定更完整的XML示例,您可能需要调整此选择。

提琴here