user4986443
user4986443

Reputation: 15

C# Deserialise XML into mutiple arrays only deserialise the first array

I have created an XSD as follows:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="TestConfiguration">
        <xs:complexType>
        <xs:sequence>

        <xs:element name="Products" minOccurs="1" maxOccurs="1">
        <xs:complexType><xs:sequence>
        <xs:element name="ProductCode" type="xs:string"  minOccurs="1" maxOccurs="1"></xs:element>
        <xs:element name="Tests" type="TestName" minOccurs="1" maxOccurs="1"></xs:element>
        </xs:sequence></xs:complexType>
        </xs:element>

        </xs:sequence>
        </xs:complexType>
    </xs:element>

<xs:complexType name="TestName">
<xs:sequence>
<xs:element name="Test" minOccurs="1" maxOccurs="unbounded" type="xs:string"></xs:element>
</xs:sequence>

</xs:complexType>
</xs:schema>

The XSD is for generating the following XML:

<?xml version="1.0" encoding="UTF-8"?>
<TestConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TibTestConfiguration.xsd">
    <Product>
        <ProductCode>B3-00</ProductCode>
        <Tests>
            <Test>DB9 Serial Port Connector</Test>
            <Test>GPRS MODEM</Test>
            <Test>SDRAM</Test>              
    </Product>
    <Product>
        <ProductCode>B3-01</ProductCode>
        <Tests>
            <Test>DB9 Serial Port Connector</Test>
            <Test>GPRS MODEM</Test>
            <Test>NAND Flash</Test>
            <Test>Main DC Power Port</Test>         
    </Product>
</TestConfiguration>

Then, I use the Microsoft Visual Studio xsd.exe to generate a class from the XSD, and it gives me:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]

    public partial class TestConfiguration
    {

        private TestConfigurationProducts productsField;


        public TestConfigurationProducts Product
        {
            get
            {
                return this.productsField;
            }
            set
            {
                this.productsField = value;
            }
        }
    }

    /// <remarks/>
    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
    public partial class TestConfigurationProducts
    {

        private string productCodeField;

        private string[] testsField;

        /// <remarks/>
        public string ProductCode
        {
            get
            {
                return this.productCodeField;
            }
            set
            {
                this.productCodeField = value;
            }
        }

        /// <remarks/>
        [System.Xml.Serialization.XmlArrayItemAttribute("Test", IsNullable = false)]
        public string[] Tests
        {
            get
            {
                return this.testsField;
            }
            set
            {
                this.testsField = value;
            }
        }
    }

When I deserialise it with the following code (file is the xml file and type is the name of the class "TestConfiguration"). it only deserialises the first product. Could you please advise what have I missed here? What I am looking for is I will have an array of "Product" which contain its own Product Code and an array of tests.

public static object DeserialiseXML(string file, Type type)
{
    string errorMsg = string.Empty;

    try
    {
        XmlSerializer serializer = new XmlSerializer(type);

        using (StreamReader reader = new StreamReader(file))
        {
            //Deserialize to object
            var deserialisedObject = serializer.Deserialize(reader);
            reader.Close();

            return deserialisedObject;
        }
    }

    catch (Exception ex)
    {
        errorMsg = ex.Message;
        return null;
    }
}       

Upvotes: 0

Views: 26

Answers (1)

Charles Mager
Charles Mager

Reputation: 26213

Your XML isn't valid per your schema. The schema says your Product element is called Products and can only appear once (maxOccurs="1"), which is why the resulting classes only have a single Product rather than an array of them.

While you could fix this and re-generate, the classes below should work:

public class TestConfiguration
{
    [XmlElement("Product")]
    public Product[] Products { get; set; }
}

public class Product
{
    public string ProductCode { get; set; }

    [XmlArrayItem("Test")]
    public string[] Tests { get; set; }
}

As an aside, your XML isn't well formed - you'll need to add closing </Tests> tags before can be deserialized.

Upvotes: 1

Related Questions