2

I am trying to load multiple elements with the same name from XML into a class using deserialisation in C#. Everything in my example loads fine but the array elements (Element3) are not populated.

Code:

class Program
{
    static void Main(string[] args)
    {
        FileStream file = new FileStream("service.xml", FileMode.Open);

        if (file != null)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(Service));
            Service service = (Service)serializer.Deserialize(file);
        }
    }
}

public class Service
{
    public bool Element1;
    public string Element2;
    public string[] Element3;
}

XML:

<Service>
    <Element1>true</Element1>
    <Element2>Text 1</Element2>
    <Element3>Text 2</Element3>
    <Element3>Text 3</Element3>
</Service>
1
  • FYI, file will never be null. Commented Sep 4, 2009 at 15:18

3 Answers 3

4

Try putting [XmlElement] on Element3.

Sign up to request clarification or add additional context in comments.

2 Comments

@John: Wow so simple :). I didn't know that was possible just with this attribute.
It's well worthwhile to read the docs on the attributes, and even to create little examples for yourself to see how they work. Sooner or later you'll need them.
2

The reason that your array isn't loading is because, as far as .NET XML Serialization is concerned, you're not trying to read an array. An array would be represented something like:

<Element3Array>
    <ArrayElement>Text 2</ArrayElement>
    <ArrayElement>Text 3</ArrayElement>
</Element3Array>

You'll need to either change the format of the source XML or create a custom XML Serializer for your class to deal with your situation.

Comments

2

I think your xml is wrong. Logically, an array is serialized like this:

<Element3>
    <string>Text 2</string>
    <string>Text 3</string>
</Element3>

So, your xml must have this format:

<Service>
    <Element1>true</Element1>
    <Element2>Text 1</Element2>
    <Element3>
        <string>Text 2</string>
        <string>Text 3</string>
    </Element3>
</Service>

Edit: Added a example to unserialize this xml if you cannot change the format. The code below is not tested.

Your class Service must derived from IXmlSerializable:

public class Service : IXmlSerializable
{
    public System.Xml.Schema.XmlSchema  GetSchema()
    {
        return null;
    }

    public void  ReadXml(System.Xml.XmlReader reader)
    {
        List<string> element3 = new List<string>();

        while (reader.Read())
        {
        if (reader.Name == "Element1" && reader.NodeType == XmlNodeType.Element)
        {
            Element1 = Convert.ToBoolean(reader.ReadString());
        }
        else if (reader.Name == "Element2" && reader.NodeType == XmlNodeType.Element)
        {
            Element2 = reader.ReadString();
        }
        if (reader.Name == "Element1" && reader.NodeType == XmlNodeType.Element)
        {
            element3.Add(reader.ReadString());
        }
        }

        Element3 = element3.ToArray();
    }

    public void  WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteStartElement ("Service"); 

        writer.WriteStartElement ("Element1"); 
        writer.WriteString(Element1.ToString());
        writer.WriteEndElement();

        writer.WriteStartElement ("Element2"); 
        writer.WriteString(Element2.ToString());
        writer.WriteEndElement();

        foreach (string ele in Element3)
        {
        writer.WriteStartElement ("Element3"); 
        writer.WriteString(ele);
        writer.WriteEndElement();
        }

        writer.WriteEndElement();
    }
}

1 Comment

@Kelix: Well if you cannot receive a xml correctly formatted for your class, you will need to create a custom Xml Serializer as suggested by Justin.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.