2

Following this link: Deserialize xml into super class object with C#

I had implemented:

xml file

<?xml version="1.0" encoding="utf-8" ?>
<xPlugins>
  <xPlugin>
    <Multiple>
      <Operator>
        <Add>
          <Operator>1</Operator>
          <Operator>2</Operator>
        </Add>        
      </Operator>
      <Operator>
        <Add>
          <Operator>3</Operator>
          <Operator>4</Operator>
        </Add>
      </Operator>
    </Multiple>
  </xPlugin>
</xPlugins>

classes

public abstract class Calculator
{
    public Calculator() { }

    public virtual int Calculate()
    {
        return 0;
    }
}

public class Operator : Calculator
{
    public int value { get; set; }

    public Operator() { }

    public Operator(string name)
    {
    }

    public override int Calculate()
    {
        return value;
    }
}

public class Add : Calculator
{
    public List<Calculator> calculators { get; set; }

    public Add() { }

    public Add(List<Calculator> calculators)
    {
        this.calculators = calculators;
    }

    public override int Calculate()
    {         
        List<int> value = new List<int>();

        foreach (Calculator calculator in calculators)
        {
            value.Add(calculator.Calculate());
        }

        return value.Sum();
    }
}

public class Minus : Calculator
{
    public List<Calculator> calculators { get; set; }

    public Minus() { }

    public Minus(List<Calculator> calculators)
    {
        this.calculators = calculators;
    }

    public override int Calculate()
    {
        int value = calculators[0].Calculate();

        for (int i = 1; i < calculators.Count; i++)
        {
            value -= calculators[i].Calculate();
        }

        return value;
    }
}

public class divide: Calculator
{
    public List<Calculator> calculators { get; set; }

    public Divide() { }

    public Divide(List<Calculator> calculators)
    {
        this.calculators = calculators;
    }

    public override int Calculate()
    {
        int value = calculators[0].Calculate();

        for (int i = 1; i < calculators.Count; i++)
        {
            value /= calculators[i].Calculate();
        }

        return value;
    }
}

public class Multiple : Calculator
{
    public List<Calculator> calculators { get; set; }

    public Multiple() { }

    public Multiple(List<Calculator> calculators)
    {
        this.calculators = calculators;
    }

    public override int Calculate()
    {
        int value = calculators[0].Calculate();

        for (int i = 1; i < calculators.Count; i++)
        {
            value *= calculators[i].Calculate();
        }

        return value;
    }
}

public class xPlugin
{        
    public Calculator calculator { get; set; }
}

public class xPlugins
{
    [XmlElement("xPlugin", typeof(xPlugin))]
    public xPlugin[] Plugin { get; set; }
}

Xml Serializer definition:

public static void getObject(ref xPlugins plugins)
    {
        try
        {
            List<Type> type = new List<Type>();
            type.Add(typeof(Add));
            type.Add(typeof(Minus));
            type.Add(typeof(Multiple));
            type.Add(typeof(Subtract));
            type.Add(typeof(Operator));

            XmlSerializer xml = new XmlSerializer(typeof(xPlugins), type.ToArray());

            FileStream fs = new FileStream("test.xml", FileMode.Open);

            plugins = (xPlugins)xml.Deserialize(fs);
        }
        catch (Exception ex)
        {
            throw;
        }
    }

Using:

private void button1_Click(object sender, EventArgs e)
    {
        readXML.getObject(ref this.plugins);

        foreach (xPlugin plugin in plugins.Plugin)
        {
            plugin.calculator.Calculate();
        }
    }

Deserialize process success to deserialize xPlugins and xPlugin into its associate class, but fail to deserialize add, multiple, divide, divide into its base class Calculator. xPlugin's calculator property always get null value. So how can I can deserialize those elements to its base class?

Community
  • 1
  • 1
Doan Cuong
  • 2,594
  • 4
  • 22
  • 39

1 Answers1

1

If you can change your xml to:

<?xml version="1.0" encoding="utf-8" ?>
<xPlugins>
  <xPlugin>
    <Multiple>
      <Operators>
        <Add>
          <Operators>
            <Operator>
              <value>1</value>
            </Operator>
            <Operator>
              <value>2</value>
            </Operator>
           </Operators>
        </Add>        
        <Add>
          <Operators>
            <Operator>
              <value>3</value>
            </Operator>
            <Operator>
              <value>4</value>
            </Operator>
            </Operators>
        </Add>
      </Operators>
    </Multiple>
  </xPlugin>
</xPlugins>

This should work:

public abstract class Calculator
{
    public Calculator() { }

    public virtual int Calculate()
    {
        return 0;
    }
}

public class Operator : Calculator
{
    public int value { get; set; }

    public Operator() { }

    public Operator(string name)
    {
    }

    public override int Calculate()
    {
        return value;
    }
}

public class Add : Calculator
{
    [XmlArray("Operators")]
    [XmlArrayItem("Add", typeof(Add))]
    [XmlArrayItem("Minus", typeof(Minus))]
    [XmlArrayItem("Multiple", typeof(Multiple))]
    [XmlArrayItem("Operator", typeof(Operator))]
    public List<Calculator> calculators { get; set; }

    public Add() { }

    public Add(List<Calculator> calculators)
    {
        this.calculators = calculators;
    }

    public override int Calculate()
    {         
        List<int> value = new List<int>();

        foreach (Calculator calculator in calculators)
        {
            value.Add(calculator.Calculate());
        }

        return value.Sum();
    }
}

public class Minus : Calculator
{
    [XmlArray("Operators")]
    [XmlArrayItem("Add", typeof(Add))]
    [XmlArrayItem("Minus", typeof(Minus))]
    [XmlArrayItem("Multiple", typeof(Multiple))]
    [XmlArrayItem("Operator", typeof(Operator))]
    public List<Calculator> calculators { get; set; }

    public Minus() { }

    public Minus(List<Calculator> calculators)
    {
        this.calculators = calculators;
    }

    public override int Calculate()
    {
        int value = calculators[0].Calculate();

        for (int i = 1; i < calculators.Count; i++)
        {
            value -= calculators[i].Calculate();
        }

        return value;
    }
}

public class Divide : Calculator
{
    [XmlArray("Operators")]
    [XmlArrayItem("Add", typeof(Add))]
    [XmlArrayItem("Minus", typeof(Minus))]
    [XmlArrayItem("Multiple", typeof(Multiple))]
    [XmlArrayItem("Operator", typeof(Operator))]
    public List<Calculator> calculators { get; set; }

    public Divide() { }

    public Divide(List<Calculator> calculators)
    {
        this.calculators = calculators;
    }

    public override int Calculate()
    {
        int value = calculators[0].Calculate();

        for (int i = 1; i < calculators.Count; i++)
        {
            value /= calculators[i].Calculate();
        }

        return value;
    }
}

public class Multiple : Calculator
{
    [XmlArray("Operators")]
    [XmlArrayItem("Add", typeof(Add))]
    [XmlArrayItem("Minus", typeof(Minus))]
    [XmlArrayItem("Multiple", typeof(Multiple))]
    [XmlArrayItem("Operator", typeof(Operator))]
    public List<Calculator> calculators { get; set; }

    public Multiple() { }

    public Multiple(List<Calculator> calculators)
    {
        this.calculators = calculators;
    }

    public override int Calculate()
    {
        int value = calculators[0].Calculate();

        for (int i = 1; i < calculators.Count; i++)
        {
            value *= calculators[i].Calculate();
        }

        return value;
    }
}

public class xPlugin
{
    [XmlElement("Add", typeof(Add))]
    [XmlElement("Minus", typeof(Minus))]
    [XmlElement("Multiple", typeof(Multiple))]
    [XmlElement("Operator", typeof(Operator))]
    public Calculator calculator { get; set; }
}

public class xPlugins
{
    [XmlElement("xPlugin", typeof(xPlugin))]
    public xPlugin[] Plugin { get; set; }
}
fcuesta
  • 4,429
  • 1
  • 18
  • 13
  • Still got null value, Sir! – Doan Cuong Jun 26 '13 at 05:48
  • I got an exception like this: http://i244.photobucket.com/albums/gg20/trongcuong1710/error-1.png. Don't know what's the cause of the problem – Doan Cuong Jun 26 '13 at 06:49
  • It works for me, are you sure you are not duplicating an XmlArrayItem.I have got the same error when I do: [XmlArrayItem("Multiple", typeof(Multiple))] [XmlArrayItem("Multiple", typeof(Divide))] – fcuesta Jun 26 '13 at 19:47
  • Thanks for your suggestion. I had solved my problem. Here is my solution http://stackoverflow.com/questions/17292634/deserialize-xml-into-super-class-object-with-c-sharp – Doan Cuong Jun 27 '13 at 06:51