Home > other >  Why do I keep getting an error when deserializing XML collection?
Why do I keep getting an error when deserializing XML collection?

Time:01-24

I have almost 1K rows of XML data and I need to deserialize them. There are no errors in the serialize / deserialize block, but my collection seems to be empty after everything is done.

#1 Main code:

public XmlSerializer xmlSerializer = new XmlSerializer(typeof(Units));

public MainForm()
{
    using (FileStream filestream = new FileStream("units.xml", FileMode.Open))
    {
        Units units = xmlSerializer.Deserialize(filestream) as Units;
        MessageBox.Show("XML COUNT: "   units.AllUnits.Count.ToString());
    }
    /* some code here */
}

#2 Data class:

    [Serializable, XmlRoot("Units")]
    public class Units
    {
        [XmlArray("Units")]
        [XmlArrayItem("Unit")]
        public List<Unit> AllUnits { get; set; }

        public Units() { }
    }

    [Serializable, XmlType("Unit")]
    public class Unit
    {
        [XmlElement("Type")]
        public String Type { get; set;  }

        [XmlElement("Name")]
        public String Name { get; set; }

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

        public Unit() { }
    }

    [Serializable]
    public struct Value
    {
        [XmlAttribute("Name")]
        public String Name { get; set; }

        [XmlElement("Value")]
        public Double ConvertValue { get; set; }
    }

#3 XML data:

<Units>
    <!-- ===================== AREA ===================== -->
    <Unit>
        <Name>SquareMeter</Name>
        <Type>Area</Type>
        <ConvertTo>
            <Value Name = "SquareMeter">1</Value>
            <Value Name = "SquareKilometer">0.000001</Value>
            <Value Name = "SquareCentimeter">10000</Value>
            <Value Name = "SquareMillimeter">1000000</Value>
            <Value Name = "SquareMicrometer">1000000000000</Value>
            <Value Name = "Hectare">0.0001</Value>
            <Value Name = "SquareMile">0.00000038610215855</Value>
            <Value Name = "SquareYard">1.19599</Value>
            <Value Name = "SquareFoot">10.7639</Value>
            <Value Name = "SquareInch">1550</Value>
            <Value Name = "Acre">0.000247105</Value>
        </ConvertTo>
    </Unit>
    <Unit>
        ...
    </Unit>
</Unit>

I also tried json for this kind of data but it seems to be a bug in my data class (#2). What should I do to make it work?

CodePudding user response:

I have made a few tweaks to your attributes.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace TestProject1Core
{
    [Serializable, XmlRoot("Units")]
    public class Units
    {
        [XmlElement("Unit")]
        public List<Unit> AllUnits { get; set; } = new List<Unit>();

        public Units() { }
    }

    [Serializable, XmlType("Unit")]
    public class Unit
    {
        [XmlElement("Type")]
        public String Type { get; set; }

        [XmlElement("Name")]
        public String Name { get; set; }

        [XmlArray("ConvertTo")]
        [XmlArrayItem("Value", ElementName ="Value")]
        public List<Value> ConvertTo { get; set; }

        public Unit() { }
    }

    [Serializable]
    public struct Value
    {
        [XmlAttribute("Name")]
        public String Name { get; set; }
        [XmlText]
        public Double ConvertValue { get; set; }
    }

    [TestClass]
    public class UnitTestXml
    {
        [TestMethod]
        public void TestXmlWrite()
        {
            var xmlSerializer = new XmlSerializer(typeof(Units));

            Units units = new Units();
            var converts = new List<Value>()
            {
                new Value() { Name="test", ConvertValue=1},
                new Value() { Name="test2", ConvertValue=2}
            };
            units.AllUnits.Add(new Unit() {  Name="test", Type = "some type", ConvertTo= converts });
            units.AllUnits.Add(new Unit() { Name = "test2", Type = "some type2", ConvertTo = converts });

            using (StringWriter writer = new StringWriter())
            {
                xmlSerializer.Serialize(writer, units);
                var x = writer.ToString();
            }

        }

        [TestMethod]
        public void TestXml()
        {
            var xmlSerializer = new XmlSerializer(typeof(Units));
            string xmlString = File.ReadAllText("testData.xml");
            Units units = xmlSerializer.Deserialize(new StringReader(xmlString)) as Units;
            Assert.IsTrue(units.AllUnits.Count > 0);

        }
    }
}
  • Related