T L
T L

Reputation: 514

deserialize XML document to C# collection of objects

I need some help to point out what I do wrong here. I have searched SO and tried different ways to load this XML and I just could not see what would have caused this error:

System.InvalidOperationException: There is an error in XML document (1, 1). ---> System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1.

<?xml version="1.0" encoding="utf-8"?>
<folderlist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<foldersetting>
  <id>1</id>
  <source>
    <path>\\USApps2\AVL\Attachments</path>
    <datelastread>2016-01-25T10:51:12.6030162-08:00</datelastread>
    <filter>
      <owner>US\</owner>
      <filetype>*</filetype>
    </filter>
  </source>
  <destination>
    <path>E:\UserData\AVL</path>
    <overwrite>false</overwrite>
  </destination>
</foldersetting>
<foldersetting>
  <id>2</id>
  <source>
    <path>\\TWAVLSVR\AVL\Attachments</path>
    <datelastread>2016-01-22T10:51:12.6030162-08:00</datelastread>
    <filter>
      <owner>TW\</owner>
      <filetype>PDF</filetype>
    </filter>
  </source>
  <destination>
    <path>E:\UserData\AVL</path>
    <overwrite>false</overwrite>
  </destination>
</foldersetting>
<foldersetting>
  <id>3</id>
  <source>
    <path>E:\UserData\AVL</path>
    <datelastread>2016-01-22T10:51:12.6030162-08:00</datelastread>
    <filter>
      <owner>US\</owner>
      <filetype>*</filetype>
    </filter>
  </source>
  <destination>
    <path>E:\UserData\AVL\Web</path>
    <overwrite>false</overwrite>
  </destination>
</foldersetting>
</folderlist>

Here is my class definition:

[Serializable()]
public class Filter
{
    [XmlElement("owner")]
    public string Owner {get; set;}

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

[Serializable()]
public class SourceFolder
{
    [XmlElement("path")]
    public string Path { get; set; }

    [XmlElement("datelastread")]
    public DateTime DateLastRead { get; set; }

    [XmlElement("filter")]
    public Filter FilterTypes { get; set; }
}

[Serializable()]
public class DestinationFolder
{
    [XmlElement("path")]
    public string Path { get; set; }

    [XmlElement("overwrite")]
    public bool OverWrite { get; set; }
}

[Serializable()]
public class FolderSetting
{
    [XmlElement("id")]
    public int ID { get; set; }

    [XmlElement("source")]
    public SourceFolder Source { get; set; }

    [XmlElement("destination")]
    public DestinationFolder Destination { get; set; }
}

[Serializable()]
[XmlRoot("folderlist")]
public class FolderList
{
    public FolderList()
    {
        FolderSettings = new List<FolderSetting>();
    }

    [XmlElement("foldersetting")]
    public List<FolderSetting> FolderSettings;
}

Here I deserialize the XML:

XmlSerializer serializer = new XmlSerializer(typeof(FolderList));
using (StringReader reader = new StringReader("C:\\Folders.xml"))
{
    FolderList folders = (FolderList)(serializer.Deserialize(reader));
}

I have followed one suggestion on here to populate the classes I have and serialize it to make sure I get the proper format for my classes and it still doesn't help. Hopefully, someone could see what I'm missing here.

Upvotes: 2

Views: 2414

Answers (2)

David Hope
David Hope

Reputation: 2256

The problem is the use of StringReader in your deserialization, you should use StreamReader:

using (StreamReader reader = new StreamReader("D:\\Folders.xml"))
{
  FolderList folders = (FolderList)(serializer.Deserialize(reader));
}

So, the result was the the serializer was attempting to deserialize "D:\Folders.xml", rather than the data file the OP was attempting to deserialize.

Upvotes: 2

Bob Platt
Bob Platt

Reputation: 11

Your XML is missing the </folderlist> end tag.

You can validate your XML here: http://www.xmlvalidation.com/

As a personal coding style, consider starting your classes with the general and move to the specific. It's easier to read when you see the top-level object first.

Upvotes: 0

Related Questions