Search code examples
c#xmlxml-deserialization

Deserialization XML to object with lists


I am trying to deserialize xml into an object but it doesn't go through the xml properly. It doesn't populate the authors in the object. I am trying to return an object that consists of articles containing a title and a list of authors. The list of authors won't populate in this code which is my issue. please help as I am new to this XML manipulation.

Here, you can see the issue. enter image description here

Here is the sample xml.

<?xml version="1.0" encoding="UTF-8"?>
<MedlineCitationSet>
<Article>
    <ArticleTitle>Title 1</ArticleTitle>
    <AuthorList>
        <Author>
            <LastName>Public</LastName>
            <ForeName>J Q</ForeName>
            <Initials>JQ</Initials>
        </Author>
        <Author>
            <LastName>Doe</LastName>
            <ForeName>John</ForeName>
            <Initials>J</Initials>
        </Author>
    </AuthorList>
</Article>
<Article>
    <ArticleTitle>Title 2</ArticleTitle>
    <AuthorList>
        <Author>
            <LastName>Doe</LastName>
            <ForeName>John</ForeName>
            <Initials>J</Initials>
        </Author>
        <Author>
            <LastName>Doe</LastName>
            <ForeName>Jane</ForeName>
            <Initials>J</Initials>
        </Author>
    </AuthorList>
</Article>  
<Article>
    <ArticleTitle>Title 3</ArticleTitle>
    <AuthorList>
        <Author>
            <LastName>Doe</LastName>
            <ForeName>Jane</ForeName>
            <Initials>J</Initials>
        </Author>
        <Author>
            <LastName>Public</LastName>
            <ForeName>J Q</ForeName>
            <Initials>JQ</Initials>
        </Author>
    </AuthorList>
</Article>
<Article>
    <ArticleTitle>Title 4</ArticleTitle>
    <AuthorList>
        <Author>
            <LastName>Smith</LastName>
            <ForeName>John</ForeName>
            <Initials>J</Initials>
        </Author>
        <Author>
            <LastName>Doe</LastName>
            <ForeName>John</ForeName>
            <Initials>J</Initials>
        </Author>
    </AuthorList>
</Article>

Here is my class hierarchy.

[XmlRoot("MedlineCitationSet")]
public class MedlineCitationSet
{
    [XmlElement("Article")]
    public List<Article> Articles { get; set; }
}

[XmlRoot("Article")]
public class Article
{
    [XmlElement("ArticleTitle")]
    public string ArticleTitle { get; set; }

    [XmlElement("AuthorList")]
    public List<Author> AuthorList { get; set; }
}

public class Author
{
    [XmlElement("LastName")]
    public string LastName { get; set; }

    [XmlElement("ForeName")]
    public string ForeName { get; set; }

    [XmlElement("Initials")]
    public string Initials { get; set; }
}

And here is my deserialization code.

XmlSerializer serializer = new XmlSerializer(typeof(MedlineCitationSet));
using (FileStream fileStream = new FileStream(newPath + @"\XmlToRead\XmlToRead.xml", FileMode.Open))
{
    MedlineCitationSet result = (MedlineCitationSet)serializer.Deserialize(fileStream);
}

Solution

  • This part:

    [XmlElement("AuthorList")]
    public List<Author> AuthorList { get; set; }
    

    Indicates that the serializer treats every <AuthorList> element as an author, instead of the extra <Author> level in your xml.

    This can be solved this way:

    [XmlArray("AuthorList")]
    [XmlArrayItem("Author")]
    public List<Author> AuthorList { get; set; }
    

    PS. You can easily see what the serializer makes of your current serialization mapping by generating a MedlineCitationSet in code and serializing it.