2

I want to deserialize xml like this:

<Product>
    <Classification>
        <NewClassification>1</NewClassification>
        <NewClassification>2</NewClassification>
        <NewClassification>3</NewClassification>
        <OldClassification>A</OldClassification>
        <OldClassification>B</OldClassification>
    </Classification>
</Product>

My classes are:

public class Product
{
    public Classification Classification { get; set; }
}

public class Classification
{
    [XmlArrayItem(typeof(int), ElementName = "NewClassification")]
    public List<int> NewClassificationList { get; set; }
    [XmlArrayItem(typeof(int), ElementName = "OldClassification")]
    public List<int> OldClassificationList { get; set; }
}

Why this code is wrong?

1
  • because A and B are not int literals? Commented Dec 9, 2009 at 16:09

1 Answer 1

3

Apart from the "int literal" issue commented on by "Bears will eat you" above, you can't serialize your class in the way you want with what you've got (at least I can't think of a way to do it) without resorting to custom serialisation (e.g. implementing IXmlSerializable or some other method).

Your basic problem is that you have two seperate collections in Classification, which you want to appear as a single collection.

The IXmlSerialization route is pretty simple though. Just implement it as follows on your Classification class, and you'll get the desired result.

public class Classification : IXmlSerializable
{
    public List<int> NewClassificationList { get; set; }
    public List<string> OldClassificationList { get; set; }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        foreach (var item in NewClassificationList)
        {
            writer.WriteElementString("NewClassification", item.ToString());
        }
        foreach (var item in OldClassificationList)
        {
            writer.WriteElementString("OldClassification", item.ToString());
        }
    }

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        throw new NotImplementedException();
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        throw new NotImplementedException();
    }
}

Added ReadXml implementation

ReadXml can be implemented as follows:

public void ReadXml(System.Xml.XmlReader reader)
{
    var product = new Product();

    product.Classification = new Classification { NewClassificationList = new List<int>(),  ldClassificationList = new List<string>()};

    reader.ReadStartElement("Classification");

    while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
    {
        switch (reader.Name)
        {
            case "NewClassification":
                product.Classification.NewClassificationList.Add(reader.ReadElementContentAsInt());
                break;
            case "OldClassification":
                product.Classification.OldClassificationList.Add(reader.ReadElementContentAsString());
                break;
            default:
                throw new NotSupportedException("Unsupported node: " + reader.Name);
           } 
        }
        reader.ReadEndElement();
    }
Sign up to request clarification or add additional context in comments.

5 Comments

I don't insist that these classifications have to be List<int> or List<string>. It might be a custom class as well.
OK. In any case, the custom serialization code above should produce exactly the output you have described in the question
How should I implement ReadXml() ? I basically want to deserialize XML into custom some class.
Sample ReadXml implementation added
My example become more complicated so I'll ask separate question. stackoverflow.com/questions/1880983/…

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.