Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserialize XML to Object Array

I'm trying to deserialize an XML file to an object array, but I'm receiving empty objects. My question looks similar to this: How to Deserialize xml to an array of objects? but I can't seem to create a class which inherits IXmlSerializable. That said, I don't think that approach is necessary.

Am I doing something wrong?

File Object

 [XmlType("file")]
    public class File
    {
        [XmlElement("id")]
        public string Id { get; set; }

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

        [XmlElement("docs")]
        public HashSet<doc> Docs { get; set; }
    }

Doc Object

 [XmlType("doc")]
    public class Doc
    {
        [XmlElement("valA")]
        public string ValA { get; set; }

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

XML

<?xml version="1.0" encoding="UTF-8"?>
  <files>
    <file>
      <id>12345</id>
      <company_name>Apple</company_name>
      <docs>
       <doc>
          <valA>Info</valA>
          <valB>More Info</valB>
       </doc>  
      </docs>
    </file>
    <file>
      <id>12345</id>
      <company_name>Microsoft</company_name>
      <docs>
       <doc>
          <valA>Even More Info</valA>
          <valB>Lots of it</valB>
       </doc>  
      </docs>
    </file>
  </files>

Deserialization code

XmlSerializer mySerializer = new XmlSerializer(typeof(File[]), new XmlRootAttribute("files"));
using (FileStream myFileStream = new FileStream("Files.xml", FileMode.Open))
{
    File[] r;
    r = (File[])mySerializer.Deserialize(myFileStream);
}
like image 293
James Stevenson Avatar asked Sep 18 '13 17:09

James Stevenson


2 Answers

You have decorated your properties with XMLAttribute but they are elements in your XML. So, change all XMLAttribute to XmlElement.

[XmlType("file")]
public class File
{
    [XmlElement("id")]
    public string Id { get; set; }

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

    [XmlArray("docs")]
    public HashSet<Doc> Docs { get; set; }
}

[XmlType("doc")]
public class Doc
{
    [XmlElement("valA")]
    public string ValA { get; set; }

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

Also you XML is not well formed. I guess this is typo though -

<company_name>Apple</company_id>
<company_name>Microsoft</company_id>

Ending tag should be company_name -

<company_name>Apple</company_name>
<company_name>Microsoft</company_name>
like image 165
Rohit Vats Avatar answered Nov 03 '22 08:11

Rohit Vats


I would use xml parser..

XDocument doc=XDocument.Load(url);
File[] r=doc.Elements("file")
            .Select(f=>
             new File
             {
                  Id=f.Element("id").Value,
                  Company_Id=f.Element("company_name").Value,
                  Docs=new HashSet<Docs>(
                       f.Elements("docs")
                        .Elements("doc")
                        .Select(d=>
                              new Doc
                              {
                                   ValA=d.Element("valA").Value,
                                   ValB=d.Element("valB").Value
                              }))
                }).ToArray();
like image 43
Anirudha Avatar answered Nov 03 '22 10:11

Anirudha