将XML反序列化为具有不同XML元素名称的对象数组

时间:2014-10-25 11:51:51

标签: c# xml serialization xml-serialization deserialization

我有一个像这样的XML结构:

<QueryResult>
    <Submission>
        <Sections>
            <Section>
                <!--Section Data-->
            </Section>
        </Sections>
    </Submission>
</QueryResult>

我正在尝试反序列化 - 我永远不必序列化 - 这是Submission对象,例如:

public partial class Submission : CanvasModel
{
    private DateTime _date;
    private DateTime _deviceDate;
    private List<Section> _sections = new List<Section>();

    [XmlIgnore]
    public ICollection<Section> Sections
    {
        get
        {
            return _sections;
        }
        set
        {
            _sections = value.ToList();
        }
    }

    //[XmlArrayItem("Section", IsNullable = false)]
    [XmlArrayItem(typeof(Section), ElementName = "Sections", IsNullable = false)]
    public Section[] SectionsArray
    {
        get
        {
            return _sections.ToArray();
        }
        set
        {
            _sections = new List<Section>(value);
        }
    }
}

然而,XML元素Sections没有反序列化。它仅在Section[]属性与XML元素Sections具有相同名称时有效。我正在与XmlArrayItem属性搏斗并且正在失败。在其他名称不同的地方,我使用XmlElement属性来指定元素名称,一切正常。但是,我不允许在同一媒体资源上使用XmlElementXmlArrayItem

使用XmlArrayItem属性将Sections XML元素反序列化为SectionsArray属性的正确方法是什么?

BTW,我希望我的EF数据模型需要广泛使用的属性public ICollection<Section> Sections有文档名称Sections,原因有几个,所以只需交换两个名称即可真的是我的最后一招。我想保留当前SectionsArray属性纯粹用于反序列化。

2 个答案:

答案 0 :(得分:2)

使用xml序列化属性会有两种方法来解决这个问题。

首先是AncientSyntax我同意的答案,唯一的修正是您必须明确为数组指定节点名称。

    [XmlRootAttribute( "Submission", Namespace = "", IsNullable = false)]
    public class Submission : CanvasModel { 
        private List<Section> _sections = new List<Section>();

    [XmlIgnore]
    public virtual ICollection<Section> Sections
    {
        get { return _sections; }
        set { _sections = value.ToList(); }
    }

    [XmlArray(ElementName="Sections")]
    [XmlArrayItem("Section", IsNullable = false)]
    public Section[] SectionsArray
    {
        get { return _sections.ToArray(); }
        set { _sections = value.ToList(); }
    }
    }

不太直接的方法是将数组包装成中间类型 像:

[SerializableAttribute()]
[XmlRootAttribute("Sections", Namespace = "", IsNullable = false)]
public partial class Sections {
    private Section[] sectionField;
    [XmlElementAttribute("Section")]
    public Section[] Section
    {
      get { return this.sectionField; }
      set { this.sectionField = value; }
    }
  }

并使用它而不是sections数组:

private Sections _sectionsArrayWrapper;
[XmlElement(typeof(Sections), ElementName = "Sections", IsNullable = false)]    
public Sections SectionsArrayWrapper
{
      // your job to go from array wrapper to collection
}

这两个定义都适用于:

[SerializableAttribute()]
[XmlRootAttribute("Section", Namespace = "", IsNullable = false)]
public class Section { }

public class CanvasModel { }

使用您提供的xml进行测试。

答案 1 :(得分:1)

ElementName应该是包含的xml元素的名称,在本例中是Section。

此外,您看起来应该使用XmlArrayAttribute以及XmlArrayItemAttribute。

[XmlArray]
[XmlArrayItem(typeof(Section), ElementName = "Section", IsNullable = false)]

有关示例,请参阅http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlarrayattribute%28v=vs.110%29.aspx